CASM  1.1.0
A Clusters Approach to Statistical Mechanics
BasicStructureIO.cc
Go to the documentation of this file.
2 
3 #include <boost/filesystem.hpp>
4 
5 #include "casm/casm_io/Log.hh"
15 
16 namespace CASM {
17 
19  jsonParser const &json) {
20  _attr.set_value(json["value"].get<Eigen::VectorXd>());
21  return json;
22 }
23 
24 //****************************************************
25 
27  json.put_obj();
28  to_json_array(_attr.value(), json["value"]);
29  return json;
30 }
31 
32 //****************************************************
34  Eigen::Ref<const Eigen::Matrix3d> const &c2f_mat) {
35  json.put_obj();
36  to_json_array(c2f_mat * apos.cart(), json["coordinate"]);
37  json["name"] = apos.name();
38  if (apos.attributes().size()) json["attributes"] = apos.attributes();
39  return json;
40 }
41 
42 //****************************************************
43 
44 void from_json(xtal::AtomPosition &apos, const jsonParser &json,
45  Eigen::Ref<const Eigen::Matrix3d> const &f2c_mat,
46  ParsingDictionary<AnisoValTraits> const &_aniso_val_dict) {
47  apos = json.get<xtal::AtomPosition>(f2c_mat, _aniso_val_dict);
48 
49  return;
50 }
51 
52 //****************************************************
53 
55  const jsonParser &json, Eigen::Matrix3d const &f2c_mat,
56  ParsingDictionary<AnisoValTraits> const &_aniso_val_dict) {
57  std::string _name;
58  Eigen::Vector3d _pos(0., 0., 0.);
59  std::map<std::string, xtal::SpeciesAttribute> attr_map;
60  if (json.is_obj()) {
61  _name = json["name"].get<std::string>();
62  if (json.contains("coordinate")) {
63  _pos = f2c_mat * json["coordinate"].get<Eigen::Vector3d>();
64  // std::cout << "f2c_mat: \n" << f2c_mat << "\n";
65  // std::cout << "_pos: " << _pos.transpose() << "\n";
66  }
67  if (json.contains("attributes")) {
68  auto it = json["attributes"].cbegin(), end_it = json["attributes"].cend();
69  for (; it != end_it; ++it) {
70  auto result_pair =
71  attr_map.emplace(it.name(), _aniso_val_dict.lookup(it.name()));
72  CASM::from_json(result_pair.first->second, *it);
73  }
74  }
75 
76  } else if (json.is_string()) {
77  _name = json.get<std::string>();
78  } else
79  throw std::runtime_error(
80  "Invalid JSON input encountered. Unable to parse AtomPosition "
81  "object.\n");
82 
83  xtal::AtomPosition result(_pos, _name);
84  result.set_attributes(attr_map);
85  return result;
86 }
87 
88 //****************************************************
89 // Write Molecule to json.
90 //****************************************************
91 
93  Eigen::Ref<const Eigen::Matrix3d> const &c2f_mat) {
94  json.put_obj();
95  CASM::to_json(mol.atoms(), json["atoms"], c2f_mat);
96  json["name"] = mol.name();
97  if (mol.attributes().size()) json["attributes"] = mol.attributes();
98 
99  return json;
100 }
101 
102 //****************************************************
103 //
104 // Read Molecule from json.
105 //
106 //****************************************************
107 
108 void from_json(xtal::Molecule &mol, const jsonParser &json,
109  Eigen::Ref<const Eigen::Matrix3d> const &f2c_mat,
110  ParsingDictionary<AnisoValTraits> const &_aniso_val_dict) {
111  std::vector<xtal::AtomPosition> _atoms;
112  if (json.contains("atoms")) {
113  CASM::from_json(_atoms, json["atoms"], f2c_mat, _aniso_val_dict);
114  }
115  mol.set_atoms(_atoms);
116 
117  std::map<std::string, xtal::SpeciesAttribute> attr_map;
118  if (json.contains("attributes")) {
119  auto it = json["attributes"].cbegin(), end_it = json["attributes"].cend();
120  for (; it != end_it; ++it) {
121  auto result_pair =
122  attr_map.emplace(it.name(), _aniso_val_dict.lookup(it.name()));
123  from_json(result_pair.first->second, *it);
124  }
125  }
126  mol.set_attributes(attr_map);
127 
128  // jsonParser tjson;
129  // to_json(mol,tjson,f2c_mat.inverse());
130  // std::cout << "Read Molecule :\n"<< json << "\n";
131 }
132 
133 //****************************************************
134 //
135 //****************************************************
136 
138  const jsonParser &json, Eigen::Ref<const Eigen::Matrix3d> const &f2c_mat,
139  ParsingDictionary<AnisoValTraits> const &_aniso_val_dict) {
140  return json.get<xtal::Molecule>(f2c_mat, _aniso_val_dict);
141 }
142 
143 //****************************************************
144 
146  const jsonParser &json, xtal::Lattice const &_home, COORD_TYPE coordtype,
147  std::map<std::string, xtal::Molecule> const &mol_map,
148  ParsingDictionary<AnisoValTraits> const &_aniso_val_dict) {
149  xtal::Site result(_home);
150  CASM::from_json(result, json, _home, coordtype, mol_map, _aniso_val_dict);
151  return result;
152 }
153 
154 //****************************************************
155 
157  COORD_TYPE coordtype) {
158  json.put_obj();
159 
160  // class xtal::Site : public Coordinate
161  if (coordtype == FRAC)
162  to_json_array(site.frac(), json["coordinate"]);
163  else
164  to_json_array(site.cart(), json["coordinate"]);
165 
166  // Occupant_DoF<Molecule> occupant_dof;
168  // change this to use FormatFlag
169  if (coordtype == FRAC) c2f = site.home().inv_lat_column_mat();
170  CASM::to_json(site.occupant_dof(), json["occupants"], c2f);
171 
172  if (site.dofs().size()) {
173  json["dofs"] = site.dofs();
174  }
175 
176  // Index m_label
177  if (valid_index(site.label())) json["label"] = site.label();
178 
179  return json;
180 }
181 
182 //****************************************************
183 
184 void from_json(xtal::Site &site, const jsonParser &json,
185  xtal::Lattice const &_home, COORD_TYPE coordtype,
186  std::map<std::string, xtal::Molecule> const &mol_map,
187  ParsingDictionary<AnisoValTraits> const &_aniso_val_dict) {
188  site.set_lattice(_home, coordtype);
189  if (coordtype == FRAC)
190  site.frac() = json["coordinate"].get<Eigen::Vector3d>();
191  else
192  site.cart() = json["coordinate"].get<Eigen::Vector3d>();
193 
194  // Index m_label -- must be greater than zero
195  Index _label = -1;
196  if (json.contains("label")) {
197  CASM::from_json(_label, json["label"]);
198  if (!valid_index(_label))
199  throw std::runtime_error("JSON specification of site has {\"label\" : " +
200  std::to_string(_label) +
201  "}, but \"label\" must be greater than 0.\n");
202  }
203  site.set_label(_label);
204 
205  // Local continuous dofs
206 
207  std::map<std::string, xtal::SiteDoFSet> _dof_map;
208  if (json.contains("dofs")) {
209  auto it = json["dofs"].begin(), end_it = json["dofs"].end();
210  for (; it != end_it; ++it) {
211  if (_dof_map.count(it.name()))
212  throw std::runtime_error(
213  "Error parsing local field \"dofs\" from JSON. DoF type " +
214  it.name() + " cannot be repeated.");
215 
216  try {
217  /* _dof_map.emplace(std::make_pair(it.name(),
218  * it->get<xtal::DoFSet>(_aniso_val_dict.lookup(it.name()))));
219  */
220  _dof_map.emplace(std::make_pair(
221  it.name(),
222  it->get<xtal::SiteDoFSet>(_aniso_val_dict.lookup(it.name()))));
223  /* _dof_map.emplace(std::make_pair(it.name(),
224  * from_json<xtal::SiteDoFSet>(*it))); */
225  } catch (std::exception &e) {
226  throw std::runtime_error(
227  "Error parsing local field \"dofs\" from JSON. Failure for DoF "
228  "type " +
229  it.name() + ": " + e.what());
230  }
231  }
232  }
233  site.set_dofs(_dof_map);
234 
235  std::vector<xtal::Molecule> t_occ;
236  std::string occ_key;
237  if (json.contains("occupants"))
238  occ_key = "occupants";
239  else if (json.contains("occupant_dof"))
240  occ_key = "occupant_dof";
241 
242  if (!occ_key.empty()) {
243  for (std::string const &occ :
244  json[occ_key].get<std::vector<std::string> >()) {
245  // std::cout << "CREATING OCCUPANT " << occ << "\n";
246  // Have convenience options for attributes like magnetic moment, etc?
247  auto it = mol_map.find(occ);
248  if (it != mol_map.end())
249  t_occ.push_back(it->second);
250  else
251  t_occ.push_back(xtal::Molecule::make_atom(occ));
252  }
253  }
254  // std::cout << "t_occ.size() = " << t_occ.size() << "\n";
255  if (t_occ.empty()) t_occ.push_back(xtal::Molecule::make_unknown());
256  site.set_allowed_occupants(t_occ);
257 }
258 
260  fs::path filename, double xtal_tol,
261  ParsingDictionary<AnisoValTraits> const *_aniso_val_dict) {
262  jsonParser json;
263  filename = fs::absolute(filename);
264  if (!fs::exists(filename)) {
265  throw std::invalid_argument("Error reading prim from file '" +
266  filename.string() + "'. Does not exist.");
267  }
268  std::ifstream f(filename.string());
269  if (!f) {
270  throw std::invalid_argument("Error reading prim from file '" +
271  filename.string() +
272  "'. Does not contain valid input.");
273  }
274  while (!f.eof() && std::isspace(f.peek())) {
275  f.get();
276  }
277 
278  // TODO: Use functions. One for checking file type, one for reading json, one
279  // for reading vasp.
280  // Check if JSON
281  if (f.peek() == '{') {
282  try {
283  json = jsonParser(f);
284  } catch (std::exception const &ex) {
285  std::stringstream err_msg;
286  err_msg << "Error reading prim from JSON file '" << filename
287  << "':" << std::endl
288  << ex.what();
289  throw std::invalid_argument(err_msg.str());
290  }
291  return read_prim(json, xtal_tol, _aniso_val_dict);
292  }
293  // else tread as vasp-like file
295  try {
297  } catch (std::exception const &ex) {
298  std::stringstream err_msg;
299  err_msg << "Error reading prim from VASP-formatted file '" << filename
300  << "':" << std::endl
301  << ex.what();
302  throw std::invalid_argument(err_msg.str());
303  }
304  return prim;
305 }
306 
309  const jsonParser &json, double xtal_tol,
310  ParsingDictionary<AnisoValTraits> const *_aniso_val_dict) {
311  ParsingDictionary<AnisoValTraits> default_aniso_val_dict =
313  if (_aniso_val_dict == nullptr) _aniso_val_dict = &default_aniso_val_dict;
314 
315  // read lattice
316  Eigen::Matrix3d latvec_transpose;
317 
318  try {
319  from_json(latvec_transpose, json["lattice_vectors"]);
320  } catch (std::exception &e) {
321  log() << e.what() << std::endl;
322  throw std::runtime_error(
323  "Error parsing global field \"lattice_vectors\" from prim JSON.");
324  }
325 
326  xtal::Lattice lat(latvec_transpose.transpose(), xtal_tol);
327 
328  // create prim using lat
329  xtal::BasicStructure prim(lat);
330 
331  // read title
332  try {
333  prim.set_title(json["title"].get<std::string>());
334  } catch (std::exception &e) {
335  log() << e.what() << std::endl;
336  throw std::runtime_error(
337  "Error parsing global field \"title\" from prim JSON.");
338  }
339 
340  Eigen::Vector3d vec;
341 
342  // Global DoFs
343  try {
344  std::map<std::string, xtal::DoFSet> _dof_map;
345  if (json.contains("dofs")) {
346  auto it = json["dofs"].begin(), end_it = json["dofs"].end();
347  for (; it != end_it; ++it) {
348  if (_dof_map.count(it.name()))
349  throw std::runtime_error(
350  "Error parsing global field \"dofs\" from prim JSON. DoF type " +
351  it.name() + " cannot be repeated.");
352 
353  try {
354  // TODO: Am I messing something up here? Why was it constructed so
355  // weird before?
356  /* _dof_map.emplace(std::make_pair(it.name(),
357  * it->get<xtal::DoFSet>(_aniso_val_dict.lookup(it.name()))));
358  */
359  _dof_map.emplace(std::make_pair(
360  it.name(),
361  it->get<xtal::DoFSet>(_aniso_val_dict->lookup(it.name()))));
362  } catch (std::exception &e) {
363  log() << e.what() << std::endl;
364  throw std::runtime_error(
365  "Error parsing global field \"dofs\" from prim JSON. Failure for "
366  "DoF type " +
367  it.name() + ": " + e.what());
368  }
369  }
370  prim.set_global_dofs(_dof_map);
371  }
372  } catch (std::exception &e) {
373  log() << e.what() << std::endl;
374  throw std::runtime_error(
375  "Error parsing global field \"dofs\" from prim JSON.");
376  }
377 
378  // read basis coordinate mode
379  COORD_TYPE mode;
380  try {
381  from_json(mode, json["coordinate_mode"]);
382  } catch (std::exception &e) {
383  log() << e.what() << std::endl;
384  throw std::runtime_error(
385  "Error parsing global field \"coordinate_mode\" from prim JSON.");
386  }
387 
388  // Molecules
389  std::map<std::string, xtal::Molecule> mol_map;
390  Eigen::Matrix3d f2c;
391  if (mode == FRAC)
392  f2c = lat.lat_column_mat();
393  else
394  f2c.setIdentity();
395 
396  try {
397  if (json.contains("species")) {
398  auto it = json["species"].begin();
399  auto it_end = json["species"].end();
400  for (; it != it_end; ++it) {
401  std::string chem_name = it.name();
402  it->get_if(chem_name, "name");
403  // log() << "chem_name: " << chem_name << "\n";
404  auto mol_it =
405  mol_map.emplace(it.name(), xtal::Molecule(chem_name)).first;
406  from_json(mol_it->second, *it, f2c, *_aniso_val_dict);
407  }
408  }
409  } catch (std::exception &e) {
410  log() << e.what() << std::endl;
411  throw std::runtime_error(
412  "Error parsing global field \"species\" from prim JSON.");
413  }
414 
415  try {
416  // read basis sites
417  for (jsonParser const &bjson : json["basis"])
418  prim.push_back(bjson.get<xtal::Site>(prim.lattice(), mode, mol_map,
419  *_aniso_val_dict));
420  } catch (std::exception &e) {
421  log() << e.what() << std::endl;
422  throw std::runtime_error(
423  "Error parsing global field \"basis\" from prim JSON.");
424  }
425  return prim;
426 }
427 
429 void write_prim(const xtal::BasicStructure &prim, fs::path filename,
430  COORD_TYPE mode, bool include_va) {
431  SafeOfstream outfile;
432  outfile.open(filename);
433 
434  jsonParser json;
435  write_prim(prim, json, mode, include_va);
436  json.print(outfile.ofstream());
437 
438  outfile.close();
439 }
440 
443  COORD_TYPE mode, bool include_va) {
444  // TODO: Use functions. One for each type that's getting serialized.
445 
446  json = jsonParser::object();
447 
448  json["title"] = prim.title();
449 
450  json["lattice_vectors"] = prim.lattice().lat_column_mat().transpose();
451 
452  if (mode == COORD_DEFAULT) {
453  mode = xtal::COORD_MODE::CHECK();
454  }
455 
456  Eigen::Matrix3d c2f_mat;
457  if (mode == FRAC) {
458  c2f_mat = prim.lattice().inv_lat_column_mat();
459  json["coordinate_mode"] = "Fractional";
460  } else if (mode == CART) {
461  c2f_mat.setIdentity();
462  json["coordinate_mode"] = "Cartesian";
463  }
464 
465  // Global DoFs
466  for (auto const &_dof : prim.global_dofs()) {
467  json["dofs"][_dof.first] = _dof.second;
468  }
469 
470  auto mol_names = allowed_molecule_unique_names(prim);
471  jsonParser &bjson = (json["basis"].put_array());
472  for (int i = 0; i < prim.basis().size(); i++) {
473  if (!include_va && prim.basis()[i].occupant_dof().size() == 1 &&
474  prim.basis()[i].occupant_dof()[0].is_vacancy())
475  continue;
476  bjson.push_back(jsonParser::object());
477  jsonParser &sjson = bjson[bjson.size() - 1];
478  jsonParser &cjson = sjson["coordinate"].put_array();
479  if (mode == FRAC) {
480  cjson.push_back(prim.basis()[i].frac(0));
481  cjson.push_back(prim.basis()[i].frac(1));
482  cjson.push_back(prim.basis()[i].frac(2));
483  } else if (mode == CART) {
484  cjson.push_back(prim.basis()[i].cart(0));
485  cjson.push_back(prim.basis()[i].cart(1));
486  cjson.push_back(prim.basis()[i].cart(2));
487  }
488 
489  if (prim.basis()[i].dofs().size()) {
490  sjson["dofs"] = prim.basis()[i].dofs();
491  }
492 
493  jsonParser &ojson = (sjson["occupants"] = jsonParser::array(
494  prim.basis()[i].occupant_dof().size()));
495 
496  for (int j = 0; j < prim.basis()[i].occupant_dof().size(); j++) {
497  ojson[j] = mol_names[i][j];
498  if (prim.basis()[i].occupant_dof()[j].name() != mol_names[i][j] ||
499  !prim.basis()[i].occupant_dof()[j].is_atomic()) {
500  to_json(prim.basis()[i].occupant_dof()[j],
501  json["species"][mol_names[i][j]], c2f_mat);
502  }
503  }
504  }
505 }
506 
507 void from_json(xtal::BasicStructure &prim, jsonParser const &json,
508  double xtal_tol,
509  ParsingDictionary<AnisoValTraits> const *_aniso_val_dict) {
510  prim = read_prim(json, xtal_tol, _aniso_val_dict);
511 }
512 
514  COORD_TYPE mode, bool include_va) {
515  write_prim(prim, json, mode, include_va);
516  return json;
517 }
518 
519 } // namespace CASM
Parsing dictionary for obtaining the correct MoleculeAttribute given a name.
T const & lookup(const key_type &_name) const
Equivalent to find, but set 'home' and throws error with suggestion if.
Write to a temporary file to ensure a good write, then rename.
Definition: SafeOfstream.hh:31
void close()
Closes stream, and if not a failed write, removes "file" and renames "file.tmp" to "file".
Definition: SafeOfstream.hh:84
void open(fs::path name, std::string tmp_ext="tmp")
Opens "file.tmp" for writing, with intended final target "file".
Definition: SafeOfstream.hh:65
fs::ofstream & ofstream()
Access underlying stream.
Definition: SafeOfstream.hh:80
bool is_string() const
Check if string.
Definition: jsonParser.cc:269
static jsonParser object()
Returns an empty json object.
Definition: jsonParser.hh:395
iterator begin()
Returns const_iterator to beginning of JSON object or JSON array.
Definition: jsonParser.cc:497
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
Definition: jsonParser.cc:601
iterator end()
Returns iterator to end of JSON object or JSON array.
Definition: jsonParser.cc:520
size_type size() const
Definition: jsonParser.cc:487
static jsonParser array()
Returns an empty json array.
Definition: jsonParser.hh:409
const_iterator cend() const
Returns const_iterator to end of JSON object or JSON array.
Definition: jsonParser.cc:533
jsonParser & put_obj()
Puts new empty JSON object.
Definition: jsonParser.hh:354
jsonParser & put_array()
Puts new empty JSON array.
Definition: jsonParser.hh:362
const_iterator cbegin() const
Returns const_iterator to beginning of JSON object or JSON array.
Definition: jsonParser.cc:510
bool is_obj() const
Check if object type.
Definition: jsonParser.cc:272
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
Definition: jsonParser.cc:188
std::string name() const
Definition: jsonParser.cc:792
An atomic species associated with a position in space.
Definition: Molecule.hh:27
BasicStructure specifies the lattice and atomic basis of a crystal.
std::map< DoFKey, DoFSet > const & global_dofs() const
static BasicStructure from_poscar_stream(std::istream &poscar_stream, double tol=TOL)
const std::string & title() const
void set_title(std::string const &_title)
Set the title of the structure.
const Lattice & lattice() const
void push_back(Site const &_site, COORD_TYPE mode=CART)
Manually set the basis sites.
void set_global_dofs(std::map< DoFKey, DoFSet > const &new_dof_map)
Manually set the global DoFs.
const std::vector< Site > & basis() const
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())
const Lattice & home() const
Access the home lattice of the coordinate.
Definition: Coordinate.hh:200
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
Definition: Coordinate.hh:562
void set_lattice(const Lattice &new_lat, COORD_TYPE mode)
Change the home lattice of the coordinate, selecting one representation (either CART or FRAC) that re...
Definition: Coordinate.cc:190
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
Definition: Coordinate.hh:550
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
Definition: Lattice.hh:110
const Eigen::Matrix3d & inv_lat_column_mat() const
Inverse of Lattice::lat_column_mat() It is the transformation matrix 'C2F', such that f = C2F * c whe...
Definition: Lattice.hh:117
Class representing a Molecule.
Definition: Molecule.hh:93
std::map< std::string, SiteDoFSet > const & dofs() const
Definition: Site.hh:78
void set_dofs(std::map< std::string, SiteDoFSet > _dofs)
Definition: Site.cc:235
const std::vector< Molecule > & occupant_dof() const
Definition: Site.cc:68
void set_label(Index _new_label)
Definition: Site.cc:252
void set_allowed_occupants(const std::vector< Molecule > &new_occ_domain)
Definition: Site.cc:228
Index label() const
access m_label;
Definition: Site.cc:119
void set_value(Eigen::Ref< const Eigen::VectorXd > const &_value)
Eigen::VectorXd const & value() const
std::string to_string(ENUM val)
Return string representation of enum class.
Definition: io_traits.hh:172
void set_attributes(std::map< std::string, SpeciesAttribute > _attr)
Set all constitutent attributes of Molecule overwrites any existing attributes.
Definition: Molecule.hh:151
std::vector< AtomPosition > const & atoms() const
Const access of all contained AtomPositions.
Definition: Molecule.hh:120
static Molecule make_atom(std::string const &atom_name)
Return an atomic Molecule with specified name.
Definition: Molecule.cc:86
Eigen::Vector3d const & cart() const
Const access of Cartesian position of atom.
Definition: Molecule.hh:43
static Molecule make_unknown()
Return an atomic Molecule with specified name.
Definition: Molecule.hh:99
void set_atoms(std::vector< AtomPosition > _atoms)
set all constituent atoms of Molecule overwrites any existing atoms
Definition: Molecule.hh:157
void set_attributes(std::map< std::string, SpeciesAttribute > _attr)
Definition: Molecule.hh:56
std::string const & name() const
Designated name of Molecule (may be unrelated to constituent species)
Definition: Molecule.hh:117
std::string const & name() const
Const access of species name.
Definition: Molecule.hh:40
std::map< std::string, SpeciesAttribute > const & attributes() const
Definition: Molecule.hh:52
std::map< std::string, SpeciesAttribute > const & attributes() const
Returns dictionary of all constituent attributes of the Molecule Does not include attributes associat...
Definition: Molecule.hh:145
std::vector< std::vector< std::string > > allowed_molecule_unique_names(BasicStructure const &_struc)
Returns an Array of each possible Molecule in this Structure.
CASM::jsonParser & to_json_array(const Eigen::MatrixBase< Derived > &value, CASM::jsonParser &json)
Write Eigen Matrix with 1 row or 1 column to JSON array.
Definition: json_io.hh:313
jsonParser & push_back(const T &value, Args &&... args)
Definition: jsonParser.hh:684
T get(Args &&... args) const
Get data from json, using one of several alternatives.
Definition: jsonParser.hh:716
IdentitySymRepBuilder Identity()
Main CASM namespace.
Definition: APICommand.hh:8
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
COORD_TYPE
Definition: enum.hh:6
Log & log()
Definition: Log.hh:424
ParsingDictionary< AnisoValTraits > make_parsing_dictionary< AnisoValTraits >()
void write_prim(const xtal::BasicStructure &prim, fs::path filename, COORD_TYPE mode, bool include_va=false)
Write prim.json to file.
Eigen::Matrix3d Matrix3d
const COORD_TYPE FRAC
Definition: enum.hh:8
xtal::BasicStructure read_prim(fs::path filename, double xtal_tol, ParsingDictionary< AnisoValTraits > const *_aniso_val_dict=nullptr)
DoFSpecsType const & get(DoFKey const &key, BasisFunctionSpecs const &basis_function_specs)
void from_json(ClexDescription &desc, const jsonParser &json)
const COORD_TYPE COORD_DEFAULT
Definition: enum.hh:11
const COORD_TYPE CART
Definition: enum.hh:9
bool valid_index(Index i)
Definition: definitions.cc:5
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
static ReturnType from_json(const jsonParser &json)
Default from_json is equivalent to.
Definition: jsonParser.hh:551