49 cur = cur->xmlChildrenNode;
52 std::string cname((
const char*)cur->name);
53 if (cname ==
"parameter")
56 std::string unit_name(
"au");
58 pAttrib.
add(pname,
"name");
59 pAttrib.
add(unit_name,
"unit");
65 double unit_conv = 1.0;
69 if (unit_name ==
"amu")
72 tspecies(iproperty, sid) = ap * unit_conv;
98 if (tspecies.size() != 0)
104 std::vector<int> nat_group;
106 std::string pname(
"none");
107 std::string randomizeR(
"no");
109 pAttrib.
add(randomizeR,
"random");
110 pAttrib.
add(nat,
"size");
111 pAttrib.
add(pname,
"name");
118 app_debug() <<
"Set the total size " << nat
119 <<
" by the 'size' attribute found in 'particleset' XML element node named '" << pname <<
"'." 123 bool ionid_found =
false;
127 int num_non_zero_group = 0;
128 bool group_found =
false;
130 processChildren(cur, [&](
const std::string& cname,
const xmlNodePtr element) {
133 else if (cname.find(
"ell") < cname.size())
135 else if (cname ==
"group")
143 const int sid = tspecies.addSpecies(sname);
147 int nat_per_group = 0;
149 gAttrib.
add(nat_per_group,
"size");
150 gAttrib.
put(element);
152 nat_group.push_back(nat_per_group);
153 ntot += nat_per_group;
154 if (nat_per_group > 0)
155 num_non_zero_group++;
164 if (nat != 0 && ntot != 0 && nat != ntot)
166 std::ostringstream msg;
167 msg <<
"The total number of particles deterimined previously was " << nat
168 <<
"but the sum of the sizes from all the 'group' XML element nodes is " << ntot
169 <<
". Please check the 'particleset' XML element node!" << std::endl;
173 if (nat == 0 && ntot != 0)
176 app_debug() <<
"Set the total size " << nat <<
" by the sum of the 'size's on all the 'group' XML element nodes." 180 if (ntot > 0 && num_non_zero_group != nat_group.size())
181 throw UniformCommunicateError(
"Some 'group' XML element node doesn't contain a 'size' attribute! 'size = 0' is not allowed in the input. Make appropriate adjustments to the input or converter.");
185 processChildren(cur, [&](
const std::string& cname,
const xmlNodePtr element) {
191 "' XML element node must include a name attribute!");
195 aAttrib.
add(size_att,
"size");
196 aAttrib.
put(element);
198 if (nat != 0 && size_att != 0 && nat != size_att)
200 std::ostringstream msg;
201 msg <<
"The total number of particles deterimined previously was " << nat
203 <<
"' XML element nodes named '" << sname <<
"' is " << size_att
204 <<
". Please check the 'particleset' XML element node!" << std::endl;
208 if (nat == 0 && size_att != 0)
212 <<
"' XML element node named '" << sname <<
"'." << std::endl;
223 std::vector<int> map_storage_to_input(nat);
224 processChildren(cur, [&](
const std::string& cname,
const xmlNodePtr element) {
230 std::vector<std::string> d_in(nat);
232 bool input_ungrouped =
false;
233 int storage_index = 0;
234 for (
int ig = 0; ig < nat_group.size(); ig++)
236 const auto& group_species_name = tspecies.getSpeciesName(ig);
237 int count_group_size = 0;
238 for (
int iat = 0; iat < nat; iat++)
240 const int element_index = tspecies.findSpecies(d_in[iat]);
241 if (element_index == tspecies.size())
243 " doesn't match any species from 'group' XML element nodes.");
244 if (element_index == ig)
246 if (iat != storage_index)
247 input_ungrouped =
true;
249 map_storage_to_input[storage_index++] = iat;
253 if (count_group_size == 0)
256 if (nat_group[ig] == 0)
257 nat_group[ig] = count_group_size;
258 else if (nat_group[ig] != count_group_size)
260 std::ostringstream msg;
261 msg <<
"The number of particles of element '" << group_species_name <<
"' from 'group' XML elment node was " 262 << nat_group[ig] <<
" but 'ionid' contains " << count_group_size <<
" entries." << std::endl;
269 app_log() <<
" Input particle set is not grouped by species. Remapping particle position indices " 272 app_debug() <<
" Species : input particle index -> internal particle index" << std::endl;
273 for (
int new_idx = 0; new_idx < map_storage_to_input.size(); new_idx++)
275 int old_idx = map_storage_to_input[new_idx];
276 if (new_idx != old_idx)
278 app_debug() <<
" " << d_in[old_idx] <<
" : " << old_idx <<
" -> " << new_idx << std::endl;
290 for (
int iat = 0; iat < nat; iat++)
292 processChildren(cur, [&](
const std::string& cname,
const xmlNodePtr element) {
301 if (nat_group.size() == 1 && nat_group[0] == 0)
310 processChildren(cur, [&](
const std::string& cname,
const xmlNodePtr child) {
311 if (cname ==
"group")
313 processChildren(child, [&](
const std::string& cname,
const xmlNodePtr element) {
317 start += nat_group[ig];
322 if (nat_group.size() > 1)
324 " without XML element node named 'ionid'." 325 " Cannot map particles to more than one species. Check XML input!");
333 if (randomizeR ==
"yes")
354 app_debug() <<
"There are " << nat <<
" particles in " << nat_group.size() <<
" species containing:" << std::endl;
355 for (
int ig = 0; ig < nat_group.size(); ig++)
358 if (nat_group[ig] == 0)
360 app_debug() <<
" " << nat_group[ig] <<
" '" << group_species_name <<
"'" << std::endl;
363 if (std::accumulate(nat_group.begin(), nat_group.end(), 0) != nat)
365 "The total number of particles doesn't match the sum of the particle counts of all the species.");
379 cur = cur->xmlChildrenNode;
382 std::string cname((
const char*)cur->name);
383 if (cname ==
"group")
387 gAttrib.
add(sname,
"name");
391 int sid = tspecies.addSpecies(sname);
409 template<
typename PAT>
416 inline bool put(xmlNodePtr cur,
int in_offset,
int copy_size,
int out_offset)
418 using data_type =
typename PAT::Type_t;
419 std::vector<data_type> data_in;
421 if (data_in.size() < in_offset + copy_size)
423 std::ostringstream msg;
424 msg <<
"Insufficient data to copy from XML input which holds " << data_in.size() <<
" entries." 425 <<
" Need to copy from [" << in_offset <<
", " << in_offset + copy_size <<
")." << std::endl;
428 std::copy_n(data_in.begin() + in_offset, copy_size,
ref_.begin() + out_offset);
435 std::string oname, otype;
440 pAttrib.
add(oname,
"name");
442 pAttrib.
add(size_in,
"size");
444 if (oname.empty() || otype.empty())
446 app_error() <<
" Missing attrib/@name or attrib/@datatype " << std::endl;
447 app_error() << R
"( <attrib name="aname" datatype="atype"/>)" << std::endl; 462 a.put(cur, in_offset, copy_size, out_offset);
468 a.put(cur, in_offset, copy_size, out_offset);
474 a.put(cur, in_offset, copy_size, out_offset);
480 a.put(cur, in_offset, copy_size, out_offset);
502 std::ofstream fxml(
FileName.c_str());
503 fxml <<
"<?xml version=\"1.0\"?>" << std::endl;
511 fxml.setf(std::ios::scientific);
514 latticeout.
get(fxml);
517 fxml <<
"<group name=\"" <<
SpeciesName[i] <<
"\"/>" << std::endl;
589 for (
int iat = 0; iat < nloc; iat++)
590 fxml <<
ref_.
R[iat] << std::endl;
593 for (
int iat = 0; iat < nloc; iat++)
620 xmlNodePtr cur = xmlNewNode(NULL, (
const xmlChar*)
"particleset");
621 xmlNewProp(cur, (
const xmlChar*)
"name", (
const xmlChar*)
ref_.
getName().c_str());
625 int nitem(mySpecies.numAttributes());
626 int nspecies(mySpecies.getTotalNum());
627 for (
int is = 0; is < nspecies; is++)
629 std::ostringstream ng;
631 xmlNodePtr g = xmlNewNode(NULL, (
const xmlChar*)
"group");
632 xmlNewProp(g, (
const xmlChar*)
"name", (
const xmlChar*)
SpeciesName[is].c_str());
633 xmlNewProp(g, (
const xmlChar*)
"size", (
const xmlChar*)ng.str().c_str());
634 for (
int item = 0; item < nitem; item++)
636 std::ostringstream prop;
637 prop << mySpecies(item, is);
638 xmlNodePtr p = xmlNewTextChild(g, NULL, (
const xmlChar*)
"parameter", (
const xmlChar*)prop.str().c_str());
639 xmlNewProp(p, (
const xmlChar*)
"name", (
const xmlChar*)mySpecies.attribName[item].c_str());
641 std::ostringstream pos;
642 pos.setf(std::ios_base::scientific);
646 pos <<
ref_.
R[iat] << std::endl;
648 xmlNodePtr posPtr = xmlNewTextChild(g, NULL, (
const xmlChar*)
"attrib", (
const xmlChar*)pos.str().c_str());
649 xmlNewProp(posPtr, (
const xmlChar*)
"name", (
const xmlChar*)
"position");
650 xmlNewProp(posPtr, (
const xmlChar*)
"datatype", (
const xmlChar*)
"posArray");
656 std::ostringstream nat;
658 xmlNewProp(cur, (
const xmlChar*)
"size", (
const xmlChar*)nat.str().c_str());
660 int nitem(mySpecies.numAttributes());
661 int nspecies(mySpecies.getTotalNum());
662 for (
int is = 0; is < nspecies; is++)
664 xmlNodePtr g = xmlNewNode(NULL, (
const xmlChar*)
"group");
665 xmlNewProp(g, (
const xmlChar*)
"name", (
const xmlChar*)
SpeciesName[is].c_str());
666 for (
int item = 0; item < nitem; item++)
668 std::ostringstream prop;
669 prop << mySpecies(item, is);
670 xmlNodePtr p = xmlNewTextChild(g, NULL, (
const xmlChar*)
"parameter", (
const xmlChar*)prop.str().c_str());
671 xmlNewProp(p, (
const xmlChar*)
"name", (
const xmlChar*)mySpecies.attribName[item].c_str());
675 std::ostringstream pos, gid;
676 pos.setf(std::ios_base::scientific);
680 pos <<
ref_.
R[iat] << std::endl;
682 xmlNodePtr posPtr = xmlNewTextChild(cur, NULL, (
const xmlChar*)
"attrib", (
const xmlChar*)pos.str().c_str());
683 xmlNewProp(posPtr, (
const xmlChar*)
"name", (
const xmlChar*)
"position");
684 xmlNewProp(posPtr, (
const xmlChar*)
"datatype", (
const xmlChar*)
"posArray");
691 xmlNodePtr gPtr = xmlNewTextChild(cur, NULL, (
const xmlChar*)
"attrib", (
const xmlChar*)gid.str().c_str());
692 xmlNewProp(gPtr, (
const xmlChar*)
"name", (
const xmlChar*)
"ionid");
693 xmlNewProp(gPtr, (
const xmlChar*)
"datatype", (
const xmlChar*)
"stringArray");
static std::string attrib_tag
the name of particle attribute node
void makeUniformRandom(ParticleAttrib< TinyVector< T, D >> &a)
void setName(const std::string &aname)
bool reset(xmlNodePtr cur)
reset the properties of a particle set
void checkGrouping(int nat, const std::vector< int > &nat_group) const
bool put(xmlNodePtr cur, int in_offset, int copy_size, int out_offset)
xmlNodePtr createNode(bool addlattice)
create particleset node
const std::string & getName() const
return the name
helper functions for EinsplineSetBuilder
ParticleScalar spins
internal spin variables for dynamical spin calculations
void reset(const char *fileroot, bool append=false) override
size_t getTotalNum() const
bool put(xmlNodePtr cur)
assign attributes to the set
std::ostream & app_error()
static std::string condition_tag
the attribute name of condition
void applyBC(const ParticlePos &pin, ParticlePos &pout)
int first(int igroup) const
return the first index of a group i
bool get(std::ostream &) const
~XMLSaveParticle() override
Attaches a unit to a Vector for IO.
int addAttribute(const std::string &aname)
for a new attribute, allocate the data, !More often used to get the index of a species ...
ParticleAttribXmlNode(PAT &a, PosUnit utype)
int getAttribType(const std::string &tname)
return a type id: one of the enum values
std::vector< std::string > SpeciesName
ParticleIndex GroupID
Species ID.
ParticleAttrib< AT > * getAttribute(const std::string &tname, const std::string &oname)
generic get function attribute function
int getTotalNum() const
return the number of species
int groups() const
return the number of groups
void createAttributeList(ATList &AttribList)
add attributes to list for IO
Specialized paritlce class for atomistic simulations.
Tensor<T,D> class for D by D tensor.
Final class and should not be derived.
const std::string & getSpeciesName(int index) const
class to handle a set of attributes of an xmlNode
This a subclass for runtime errors that will occur on all ranks.
declaration of ProgressReportEngine
void convert2Cart(const ParticlePos &pin, ParticlePos &pout)
bool put(xmlNodePtr cur) override
virtual void begin_node(std::ostream &os) const
write the start of a node
QTFull::RealType Scalar_t
bool readXML(xmlNodePtr cur)
process xmlnode <particleset/> which contains everything about the particle set to initialize ...
int last(int igroup) const
return the last index of a group i
static std::string ionid_tag
the name for ionid attribute
std::string getXMLAttributeValue(const xmlNodePtr cur, const std::string_view name)
get the value string for attribute name if name is unfound in cur you get an empty string back this i...
void getPtclAttrib(xmlNodePtr cur, int in_offset, int copy_size, int out_offset)
read the data of a particle attribute
static std::string datatype_tag
the attribute name of datatype
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
void create(const std::vector< int > &agroup)
create grouped particles
std::vector< std::string > speciesName
Species name list.
void setMapStorageToInput(const std::vector< int > &mapping)
bool putContent(T &a, xmlNodePtr cur)
replaces a's value with the first "element" in the "string" returned by XMLNodeString{cur}.
void report(int iter) override
void processChildren(const xmlNodePtr cur, const F &functor)
process through all the children of an XML element F is a lambda or functor void F/[](const std::stri...
sycl::event copy_n(sycl::queue &aq, const T1 *restrict VA, size_t array_size, T2 *restrict VC, const std::vector< sycl::event > &events)
void get(std::ostream &os, int olevel) const
static std::string stringtype_tag
the datatype tag for the string-type attribute
PosUnit
enum class to assist copy and unit conversion operations on position vectors
XMLSaveParticle(Particle_t &pin)
const auto & getLattice() const
void createSK()
create Structure Factor with PBCs
XMLParticleParser(Particle_t &aptcl)
constructor
Custom container for set of attributes for a set of species.
void setSpeciesProperty(SpeciesSet &tspecies, int sid, xmlNodePtr cur)
set the property of a SpeciesSet
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
AttribListType ref_AttribList
virtual void end_node(std::ostream &os) const
write the end of a node