1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2008-2012 The Regents of the University of California
4 //
5 // This file is part of Qbox
6 //
7 // Qbox is distributed under the terms of the GNU General Public License
8 // as published by the Free Software Foundation, either version 2 of
9 // the License, or (at your option) any later version.
10 // See the file COPYING in the root directory of this distribution
11 // or <http://www.gnu.org/licenses/>.
12 //
13 ////////////////////////////////////////////////////////////////////////////////
14 //
15 // SpeciesHandler.cpp
16 //
17 ////////////////////////////////////////////////////////////////////////////////
18 
19 #include "SpeciesHandler.h"
20 #include "Species.h"
21 #include "StrX.h"
22 using namespace xercesc;
23 #include <iostream>
24 #include <sstream>
25 #include <cassert>
26 using namespace std;
27 
28 ////////////////////////////////////////////////////////////////////////////////
SpeciesHandler(Species & sp)29 SpeciesHandler::SpeciesHandler(Species& sp) :
30   sp_(sp), d_ij_alloc(false) {}
31 
32 ////////////////////////////////////////////////////////////////////////////////
~SpeciesHandler()33 SpeciesHandler::~SpeciesHandler() {}
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 // read attributes
read(const Attributes & attributes)37 void SpeciesHandler::read(const Attributes& attributes)
38 {
39   unsigned int len = attributes.getLength();
40   for ( unsigned int index = 0; index < len; index++ )
41   {
42     string attrname = StrX(attributes.getLocalName(index)).localForm();
43     if ( attrname == "l" )
44     {
45       current_l = atoi(StrX(attributes.getValue(index)).localForm());
46     }
47     else if ( attrname == "size" )
48     {
49       current_size = atoi(StrX(attributes.getValue(index)).localForm());
50     }
51     else if ( attrname == "i" )
52     {
53       current_i = atoi(StrX(attributes.getValue(index)).localForm()) - 1;
54     }
55     else if ( attrname == "j" )
56     {
57       current_j = atoi(StrX(attributes.getValue(index)).localForm()) - 1;
58     }
59   }
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 // allocate array for d_ij matrix
alloc_d_ij()64 void SpeciesHandler::alloc_d_ij()
65 {
66   // allocate for every l
67   sp_.d_.resize(sp_.proj_.size());
68   for ( int l = 0; l < sp_.d_.size(); l++ )
69   {
70     const int size = sp_.proj_[l].size();
71     sp_.d_[l].resize(size);
72     for ( int i = 0; i < size; i++ )
73     {
74       sp_.d_[l][i].resize(size);
75     }
76   }
77   d_ij_alloc = true;
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
startElement(const XMLCh * const uri,const XMLCh * const localname,const XMLCh * const qname,const Attributes & attributes)81 void SpeciesHandler::startElement(const XMLCh* const uri,
82   const XMLCh* const localname, const XMLCh* const qname,
83   const Attributes& attributes)
84 {
85 //  cout << " SpeciesHandler::startElement " << StrX(qname) << endl;
86 
87   string locname = StrX(localname).localForm();
88 
89   if ( locname == "species" )
90   {
91     // check for the case where the species is a link to another uri
92     unsigned int len = attributes.getLength();
93     for ( unsigned int index = 0; index < len; index++ )
94     {
95       string attrname = StrX(attributes.getLocalName(index)).localForm();
96       if ( attrname == "name" )
97       {
98         current_name = StrX(attributes.getValue(index)).localForm();
99         sp_.name_ = current_name;
100       }
101       else if ( attrname == "href" )
102       {
103         current_href = StrX(attributes.getValue(index)).localForm();
104         sp_.uri_ = current_href;
105       }
106     }
107   }
108   else if ( locname == "norm_conserving_pseudopotential" )
109   {
110     sp_.type_ = Species::NCPP;
111   }
112   else if ( locname == "norm_conserving_semilocal_pseudopotential" )
113   {
114     sp_.type_ = Species::SLPP;
115   }
116   else if ( locname == "core_density" )
117   {
118     read(attributes);
119   }
120   else if ( locname == "local_potential" )
121   {
122     read(attributes);
123   }
124   else if ( locname == "projector" )
125   {
126     read(attributes);
127   }
128   else if ( locname == "d_ij" )
129   {
130     read(attributes);
131   }
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
endElement(const XMLCh * const uri,const XMLCh * const localname,const XMLCh * const qname,string & content)135 void SpeciesHandler::endElement(const XMLCh* const uri,
136   const XMLCh* const localname, const XMLCh* const qname, string& content)
137 {
138   string locname = StrX(localname).localForm();
139   istringstream stst(content);
140 
141   if ( locname == "description" )
142   {
143     // reject ambiguous case where both the href and the definition are given
144     if ( current_href != "" )
145     {
146       cout << " SpeciesHandler: ambiguous definition: uri=" << StrX(uri)
147         << endl << " using local definition (href: " << current_href
148         << " ignored)" << endl;
149     }
150     sp_.description_ = content;
151   }
152   else if ( locname == "atomic_number" )
153   {
154     stst >> sp_.atomic_number_;
155   }
156   else if ( locname == "mass" )
157   {
158     stst >> sp_.mass_;
159   }
160   else if ( locname == "symbol" )
161   {
162     stst >> skipws >> sp_.symbol_;
163   }
164   else if ( locname == "valence_charge" )
165   {
166     stst >> sp_.zval_;
167   }
168   else if ( locname == "lmax" )
169   {
170     stst >> sp_.lmax_;
171   }
172   else if ( locname == "llocal" )
173   {
174     stst >> sp_.llocal_;
175   }
176   else if ( locname == "nquad" )
177   {
178     stst >> sp_.nquad_;
179   }
180   else if ( locname == "rquad" )
181   {
182     stst >> sp_.rquad_;
183   }
184   else if ( locname == "mesh_spacing" )
185   {
186     stst >> sp_.deltar_;
187   }
188   else if ( locname == "radial_potential" )
189   {
190     assert(sp_.type_ == Species::NCPP);
191     if ( current_l + 1 > sp_.vps_.size() )
192     {
193       sp_.vps_.resize(current_l + 1);
194       sp_.phi_.resize(current_l + 1);
195     }
196     sp_.vps_[current_l].resize(current_size);
197     for ( int i = 0; i < current_size; i++ )
198       stst >> sp_.vps_[current_l][i];
199   }
200   else if ( locname == "local_potential" )
201   {
202     assert(sp_.type_ == Species::SLPP);
203     sp_.vlocal_.resize(current_size);
204     for ( int i = 0; i < current_size; i++ )
205       stst >> sp_.vlocal_[i];
206   }
207   else if ( locname == "radial_function" )
208   {
209     assert(sp_.type_ == Species::NCPP);
210     sp_.phi_[current_l].resize(current_size);
211     for ( int i = 0; i < current_size; i++ )
212       stst >> sp_.phi_[current_l][i];
213   }
214   else if ( locname == "core_density" )
215   {
216     // read charge for nonlinear core correction
217     sp_.nlcc_.resize(current_size);
218     for ( int i = 0; i < current_size; i++ )
219       stst >> sp_.nlcc_[i];
220   }
221   else if ( locname == "projector" and sp_.type_ == Species::SLPP )
222   {
223     // read one of the projector with this angular momentum
224     // resize vector if necessary
225     if ( current_l >= sp_.proj_.size() ) sp_.proj_.resize(current_l + 1);
226     if ( current_i >= sp_.proj_[current_l].size() )
227       sp_.proj_[current_l].resize(current_i + 1);
228     sp_.proj_[current_l][current_i].resize(current_size);
229     // read the projector
230     for ( int i = 0; i < current_size; i++ )
231       stst >> sp_.proj_[current_l][current_i][i];
232   }
233   else if ( locname == "d_ij" )
234   {
235     assert(sp_.type_ == Species::SLPP);
236     if ( not d_ij_alloc ) alloc_d_ij();
237     assert(current_l < sp_.d_.size());
238     assert(current_i < sp_.d_[current_l].size());
239     assert(current_j < sp_.d_[current_l][current_i].size());
240     stst >> sp_.d_[current_l][current_i][current_j];
241   }
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
startSubHandler(const XMLCh * const uri,const XMLCh * const localname,const XMLCh * const qname,const Attributes & attributes)245 StructureHandler* SpeciesHandler::startSubHandler(const XMLCh* const uri,
246   const XMLCh* const localname, const XMLCh* const qname,
247   const Attributes& attributes)
248 {
249   // check if element qname can be processed by another StructureHandler
250   // If it can, return a pointer to the StructureHandler, otherwise return 0
251   // cout << " SpeciesHandler::startSubHandler " << StrX(qname) << endl;
252   return 0;
253 }
254 
255 ////////////////////////////////////////////////////////////////////////////////
endSubHandler(const XMLCh * const uri,const XMLCh * const localname,const XMLCh * const qname,const StructureHandler * const subHandler)256 void SpeciesHandler::endSubHandler(const XMLCh* const uri,
257   const XMLCh* const localname, const XMLCh* const qname,
258   const StructureHandler* const subHandler)
259 {
260   // cout << " SpeciesHandler::endSubHandler " << StrX(qname) << endl;
261   // if any StructureHandler was created by startSubHandler, delete it
262   // delete subHandler;
263 }
264