CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
Configuration.cc
Go to the documentation of this file.
2 
3 #include <sstream>
4 //#include "casm/misc/Time.hh"
5 #include "casm/clex/PrimClex.hh"
6 #include "casm/clex/Supercell.hh"
10 #include "casm/casm_io/VaspIO.hh"
16 
17 namespace CASM {
18 
19  const std::string QueryTraits<Configuration>::name = "Configuration";
20 
21  template class QueryHandler<Configuration>;
22 
23  namespace {
24  typedef std::insert_iterator<std::map<std::string, std::shared_ptr<RuntimeLibrary> > > runtimelib_it_type;
25  typedef std::insert_iterator<DataFormatterDictionary<Configuration> > config_dict_it_type;
26  }
27 
28  template std::pair<config_dict_it_type, runtimelib_it_type> load_query_plugins(
29  const ProjectSettings &set,
30  config_dict_it_type dict_it,
31  runtimelib_it_type lib_it);
32 
33 
34 
36  Configuration::Configuration(Supercell &_supercell, const jsonParser &src, const ConfigDoF &_configdof)
37  : id("none"), supercell(&_supercell), source_updated(true), multiplicity(-1),
38  m_configdof(_configdof), prop_updated(true), m_selected(false) {
39  set_source(src);
40  }
41 
42  //*********************************************************************************
44  Configuration::Configuration(const jsonParser &json, Supercell &_supercell, Index _id)
45  : supercell(&_supercell), source_updated(false), multiplicity(-1),
46  m_configdof(_supercell.num_sites()), prop_updated(false) {
47 
48  std::stringstream ss;
49  ss << _id;
50  id = ss.str();
51 
52  read(json);
53  }
54 
55  //********** MUTATORS ***********
56 
58  std::stringstream ss;
59  ss << _id;
60  id = ss.str();
61 
62  prop_updated = true;
63  }
64 
65  //*********************************************************************************
66  void Configuration::set_source(const jsonParser &source) {
67  if(source.is_null() || source.size() == 0) {
69  }
70  else if(!source.is_array()) {
72  m_source.push_back(source);
73  }
74  else {
75  m_source = source;
76  }
77  source_updated = true;
78  }
79 
80  //*********************************************************************************
82 
83  if(source.is_null() || source.size() == 0) {
84  return;
85  }
86  if(!source.is_array()) {
87 
88  // check if the new source is already listed, if it is do nothing
89  for(int i = 0; i < m_source.size(); i++) {
90  if(m_source[i] == source)
91  return;
92  }
93 
94  // else, add the new source
95  m_source.push_back(source);
96 
97  source_updated = true;
98  }
99  else {
100 
101  // check all new sources, if already listed skip, if the any of the new sources is already listed, if it is do nothing
102 
103  for(int s = 0; s < source.size(); s++) {
104 
105  bool found = false;
106 
107  for(int i = 0; i < m_source.size(); i++) {
108  if(m_source[i] == source[s]) {
109  found = true;
110  break;
111  }
112  }
113 
114  if(!found) {
115  // else, add the new source
116  m_source.push_back(source[s]);
117 
118  source_updated = true;
119  }
120  }
121  }
122  }
123 
124  //*********************************************************************************
126  _invalidate_id();
127  m_configdof.clear();
128  }
129 
130  //*********************************************************************************
132  set_occupation(Array<int>(this->size(), 0));
133  }
134 
135  //*********************************************************************************
136  void Configuration::set_occupation(const Array<int> &new_occupation) {
137  _invalidate_id();
138  if(new_occupation.size() != this->size()) {
139  default_err_log().error("Configuration::set_occupation size error");
140  default_err_log() << "new_occupation.size(): " << new_occupation.size() << std::endl;
141  default_err_log() << "Configuration size(): " << this->size() << std::endl;
142  throw std::runtime_error("Error: Configuration::set_occupation with array of the wrong size");
143  }
144  m_configdof.set_occupation(new_occupation);
145  return;
146  }
147 
148  //*********************************************************************************
149  void Configuration::set_occ(Index site_l, int val) {
150  _invalidate_id();
151  m_configdof.occ(site_l) = val;
152  }
153 
154  //*********************************************************************************
157  }
158 
159  //*********************************************************************************
161  set_displacement(displacement_matrix_t::Zero(3, this->size()));
162  }
163 
164  //*********************************************************************************
166  _invalidate_id();
167  if(new_displacement.cols() != this->size()) {
168  default_err_log().error("Configuration::set_displacement size error");
169  default_err_log() << "new_displacement.cols(): " << new_displacement.cols() << std::endl;
170  default_err_log() << "Configuration size(): " << this->size() << std::endl;
171  throw std::runtime_error("Error: Configuration::set_displacement with matrix of the wrong size");
172  }
173  m_configdof.set_displacement(new_displacement);
174  }
175 
176  //*********************************************************************************
177  void Configuration::set_disp(Index site_l, const Eigen::VectorXd &_disp) {
178  _invalidate_id();
179  m_configdof.disp(site_l) = _disp;
180  }
181 
182  //*********************************************************************************
184  _invalidate_id();
186  }
187 
188  //*********************************************************************************
190  set_deformation(Eigen::Matrix3d::Identity());
191  }
192 
193  //*********************************************************************************
194 
195  void Configuration::set_deformation(const Eigen::Matrix3d &new_deformation) {
196  _invalidate_id();
197  m_configdof.set_deformation(new_deformation);
198  }
199 
200  //*********************************************************************************
201 
203  _invalidate_id();
205  }
206 
207  //*******************************************************************************
208 
211  return (find_translation() == get_supercell().translate_end());
212  }
213 
214  //*******************************************************************************
215 
222  const Supercell &scel = get_supercell();
223  auto begin = scel.translate_begin();
224  auto end = scel.translate_end();
225  if(++begin == end) {
226  return end;
227  }
228  return std::find_if(begin, end, f);
229  }
230 
231  //*******************************************************************************
232 
238  Configuration tconfig {*this};
239  /*
240  std::cout << "T: \n" << tconfig.get_supercell().get_transf_mat() << std::endl;
241  std::cout << "L: \n" << tconfig.get_supercell().get_real_super_lattice().lat_column_mat() << std::endl;
242  */
243 
244  std::unique_ptr<Supercell> next_scel;
245 
246  // check if config is primitive, and if not, obtain a translation that maps the config on itself
247  while(true) {
248 
249  PermuteIterator result = tconfig.find_translation();
250  if(result == tconfig.get_supercell().translate_end()) {
251  break;
252  }
253 
254  // replace one of the lattice vectors with the translation
255  Lattice new_lat = replace_vector(
256  tconfig.ideal_lattice(),
257  result.sym_op().tau(),
258  crystallography_tol()).make_right_handed().get_reduced_cell();
259 
260  next_scel.reset(new Supercell(&get_primclex(), new_lat));
261  /*
262  std::cout << "T: \n" << next_scel->get_transf_mat() << std::endl;
263  std::cout << "L: \n" << next_scel->get_real_super_lattice().lat_column_mat() << std::endl;
264  */
265 
266  // create a sub configuration in the new supercell
267  tconfig = sub_configuration(*next_scel, tconfig);
268  //std::cout << "sub occ: \n" << tconfig.occupation() << std::endl;
269 
270  tconfig.m_supercell_ptr.reset(next_scel.release());
271  tconfig.supercell = tconfig.m_supercell_ptr.get();
272 
273  }
274 
275  return tconfig;
276  }
277 
278  //*******************************************************************************
279 
282  const Supercell &scel = get_supercell();
284  return std::all_of(
285  ++scel.permute_begin(),
286  scel.permute_end(),
287  [&](const PermuteIterator & p) {
288  return f(p) || !f.is_less();
289  });
290  }
291 
292  //*******************************************************************************
293 
297  const Supercell &scel = get_supercell();
298  return std::max_element(scel.permute_begin(), scel.permute_end(), f);
299  }
300 
301  //*******************************************************************************
302 
305  return to_canonical().inverse();
306  }
307 
308  //*******************************************************************************
309 
312  return copy_apply(to_canonical(), (*this));
313  }
314 
315  //*******************************************************************************
316 
321 
322  Supercell &canon_scel = get_supercell().canonical_form();
323 
324  FillSupercell f(canon_scel, *this, crystallography_tol());
325  Configuration in_canon = f(*this);
326 
327  // only OK to use if canon_scel and this->get_supercell() are stored in
328  // primclex supercell list
329  //Configuration in_canon = get_primclex().fill_supercell(canon_scel, *this);
330 
331  return in_canon.canonical_form();
332  }
333 
334  //*******************************************************************************
335 
346  ConfigInsertResult Configuration::insert(bool primitive_only) const {
347 
348  ConfigInsertResult res;
349 
350  Configuration pconfig = this->primitive().in_canonical_supercell();
351  Supercell &canon_scel = pconfig.get_supercell();
352  Index config_index;
353 
354  res.insert_primitive = canon_scel.add_canon_config(pconfig, config_index);
355 
357  &get_primclex(),
358  canon_scel.get_id(),
359  config_index);
360 
361  // if the primitive supercell is the same as the equivalent canonical supercell
362  if(get_supercell().canonical_form() == pconfig.get_supercell()) {
364  res.canonical_it = res.primitive_it;
365  }
366  else {
367  if(primitive_only) {
368  res.insert_canonical = false;
369  }
370  else {
371  // primitive is returned as canonical form in canonical supercell
372  Supercell &canon_scel = get_supercell().canonical_form();
373  Index config_index;
375 
376  res.insert_canonical = canon_scel.add_config(this->in_canonical_supercell(), config_index, permute_it);
377 
379  &get_primclex(),
380  canon_scel.get_id(),
381  config_index);
382  }
383  }
384  return res;
385  }
386 
387  //*******************************************************************************
388 
391  std::vector<PermuteIterator> Configuration::factor_group() const {
392  std::vector<PermuteIterator> fg;
394  const Supercell &scel = get_supercell();
395  std::copy_if(scel.permute_begin(), scel.permute_end(), std::back_inserter(fg), f);
396  return fg;
397  }
398 
399  //*******************************************************************************
400 
403  SymGroup sym_group;
404  sym_group.set_lattice(ideal_lattice());
405  std::vector<PermuteIterator> config_factor_group;
406  config_factor_group = factor_group();
407  bool new_symop;
408  for(int i = 0; i < config_factor_group.size(); i++) {
409  new_symop = true;
410  if(i > 0) {
411  if(config_factor_group[i].factor_group_index() == config_factor_group[i - 1].factor_group_index())
412  new_symop = false;
413  }
414  if(new_symop)
415  sym_group.push_back(config_factor_group[i].sym_op());
416  }
417  return sym_group;
418  }
419 
420  //*******************************************************************************
421 
424  FillSupercell f(scel, op);
425  return f(*this);
426 
427  // only OK to use if both supercells are stored in primclex supercell list:
428  //return get_primclex().fill_supercell(scel, *this, op);
429  }
430 
431  //*******************************************************************************
432 
437 
438  auto res = is_supercell(
439  scel.get_real_super_lattice(),
440  ideal_lattice(),
441  g.begin(),
442  g.end(),
444 
445  if(res.first == g.end()) {
446 
447  std::cerr << "Requested supercell transformation matrix: \n"
448  << scel.get_transf_mat() << "\n";
449  std::cerr << "Requested motif Configuration: " <<
450  name() << "\n";
451  std::cerr << "Configuration transformation matrix: \n"
452  << get_supercell().get_transf_mat() << "\n";
453 
454  throw std::runtime_error(
455  "Error in 'Configuration::fill_supercell(const Supercell &scel, const SymGroup& g)'\n"
456  " The motif cannot be tiled onto the specified supercell."
457  );
458  }
459 
460  return fill_supercell(scel, *res.first);
461  }
462 
463  //*********************************************************************************
465  prop_updated = true;
466  calculated = calc;
467  }
468 
469  //*********************************************************************************
470 
472  //std::cout << "begin Configuration::read_calculated()" << std::endl;
473  bool success = true;
476  fs::path filepath = calc_properties_path();
477  //std::cout << "filepath: " << filepath << std::endl;
478  parsed_props = jsonParser();
479  if(fs::exists(filepath)) {
480  jsonParser json(filepath);
481 
482  //Record file timestamp
483  parsed_props["data_timestamp"] = fs::last_write_time(filepath);
484 
485  std::vector<std::string> props = get_primclex().settings().properties();
486  for(Index i = 0; i < props.size(); i++) {
487  //std::cout << "checking for: " << props[i] << std::endl;
488  if(json.contains(props[i])) {
489 
490  // normal by #prim cells for some properties
491  if(props[i] == "energy" || props[i] == "relaxed_energy" || props[i] == "relaxed_magmom") {
492  parsed_props[ props[i] ] = json[props[i]].get<double>() / get_supercell().volume();
493  }
494  else {
495  parsed_props[props[i]] = json[props[i]];
496  }
497  }
498  else
499  success = false;
500  }
501  //Get relaxed magmom:
502  if(json.contains("relaxed_magmom")) {
503  parsed_props["relaxed_magmom"] = json["relaxed_magmom"].get<double>() / get_supercell().volume();
504  }
505  //Get RMS force:
506  if(json.contains("relaxed_forces")) {
507  if(json["relaxed_forces"].size()) {
508  Eigen::MatrixXd forces;
509  from_json(forces, json["relaxed_forces"]);
510  parsed_props["rms_force"] = sqrt((forces.transpose() * forces).trace() / double(forces.rows()));
511  }
512  else {
513  parsed_props["rms_force"] = 0.;
514  }
515  }
516  //Get Magnetic moment per site:
517  if(json.contains("relaxed_mag_basis")) {
518 
519  // get the number of each molecule type
520  std::vector<int> num_each_molecule;
521  std::vector<std::string> name_each_molecule;
522  from_json(num_each_molecule, json["atoms_per_type"]);
523  from_json(name_each_molecule, json["atom_type"]);
524 
525  // need to create an unsort_dict to put measured properties in the 'right' place
526  auto struc_molecule_name = get_prim().get_struc_molecule_name();
527 
528  // Initialize container
529  Eigen::VectorXd mag_each_molecule = Eigen::VectorXd::Constant(struc_molecule_name.size(), std::nan(""));
530 
531  Index i; // Index for which atom_type we're looking at
532  Index j; // Index for which individual atom of that atom_type
533  Index k = 0; // Global index over all atoms in the configuration
534  double cum_molecule_mag; // Holder for the cumulative magmom for the current atom_type
535 
536  for(i = 0; i < num_each_molecule.size(); i++) {
537  cum_molecule_mag = 0;
538  for(j = 0; j < num_each_molecule[i]; j++) {
539  cum_molecule_mag += json["relaxed_mag_basis"][k].get<double>();
540  k += 1;
541  }
542  auto atom_idx = std::find(struc_molecule_name.begin(), struc_molecule_name.end(), name_each_molecule[i]) - struc_molecule_name.begin();
543  if(atom_idx < struc_molecule_name.size()) {
544  mag_each_molecule[atom_idx] = cum_molecule_mag / num_each_molecule[i];
545  }
546  parsed_props["relaxed_mag"] = mag_each_molecule;
547  }
548  }
549  }
550  else
551  success = false;
552 
553  return success;
554  }
555 
556  //********** ACCESSORS ***********
557 
560  }
561 
562  //*********************************************************************************
563 
564  std::string Configuration::get_id() const {
565  return id;
566  }
567 
568  //*********************************************************************************
586  std::string Configuration::name() const {
587  if(m_name.empty()) {
588  _generate_name();
589  }
590  return m_name;
591  }
592 
594  m_name = get_supercell().get_name() + "/" + get_id();
595  }
596 
597  //*********************************************************************************
598  std::string Configuration::calc_status() const {
599  if(fs::exists(calc_status_path())) {
601  if(json.contains("status"))
602  return json["status"].get<std::string>();
603  }
604  return("not_submitted");
605  }
606 
607  //*********************************************************************************
608  std::string Configuration::failure_type() const {
609  if(fs::exists(calc_status_path())) {
611  if(json.contains("failure_type"))
612  return json["failure_type"].get<std::string>();
613  }
614  return("none");
615  }
616 
617  //*********************************************************************************
619  return m_source;
620  }
621 
622  //*********************************************************************************
624  return get_supercell().get_path() / get_id();
625  }
626 
627  //*********************************************************************************
630  return get_supercell().num_sites();
631  }
632 
633  //*********************************************************************************
635  return get_supercell().get_prim();
636  }
637 
638  //*********************************************************************************
639  //PrimClex &Configuration::get_primclex() {
640  //return get_supercell().get_primclex();
641  //}
642 
643  //*********************************************************************************
645  return get_supercell().get_primclex();
646  }
647 
648  //*********************************************************************************
650  return *supercell;
651  }
652 
653  //*********************************************************************************
656  }
657 
658  //*********************************************************************************
660  return get_supercell().uccoord(site_l);
661  }
662 
663  //*********************************************************************************
664  int Configuration::get_b(Index site_l) const {
665  return get_supercell().get_b(site_l);
666  }
667 
668  //*********************************************************************************
669  const Molecule &Configuration::get_mol(Index site_l) const {
670  return get_prim().basis[ get_b(site_l) ].site_occupant()[ occ(site_l) ];
671  }
672 
673  //*********************************************************************************
675  return calculated;
676  }
677 
678  //*********************************************************************************
679  /*
680  const DeltaProperties &Configuration::delta_properties() const {
681  return delta;
682  }
683  */
684  //*********************************************************************************
685 
687  return generated;
688  }
689 
690  //*********************************************************************************
691 
692  /*const Correlation &Configuration::get_correlations() const {
693  return correlations;
694  }*/
695 
696  //*********************************************************************************
697 
701 
702  // get the number of each molecule
703  Array< Array < int > > sublat_num_each_molecule = get_sublat_num_each_molecule();
704  Array< Array < double > > sublattice_composition(sublat_num_each_molecule.size());
705 
706  // divide by number of sites per sublattice ( supercell volume )
707  for(Index i = 0; i < sublat_num_each_molecule.size(); i++) {
708  sublattice_composition[i].resize(sublat_num_each_molecule[i].size());
709  for(Index j = 0; j < sublat_num_each_molecule[i].size(); j++) {
710  sublattice_composition[i][j] = (1.0 * sublat_num_each_molecule[i][j]) / get_supercell().volume();
711  }
712  }
713 
714  return sublattice_composition;
715  }
716 
717  //*********************************************************************************
722 
723  Index i;
724 
725  // [basis_site][site_occupant_index]
726  auto convert = get_index_converter(get_prim(), get_prim().get_struc_molecule());
727 
728  // create an array to count the number of each molecule
729  Array< Array<int> > sublat_num_each_molecule;
730  for(i = 0; i < get_prim().basis.size(); i++) {
731  sublat_num_each_molecule.push_back(Array<int>(get_prim().basis[i].site_occupant().size(), 0));
732  }
733 
734  // count the number of each molecule by sublattice
735  for(i = 0; i < size(); i++) {
736  sublat_num_each_molecule[ get_b(i) ][occ(i)]++;
737  }
738 
739  return sublat_num_each_molecule;
740  }
741 
742  //*********************************************************************************
746 
747  // get the number of each molecule type
748  Array<int> num_each_molecule = get_num_each_molecule();
749 
751  int num_atoms = 0;
752 
753  // need to know which molecules are vacancies
754  auto struc_molecule = get_prim().get_struc_molecule();
755 
756  Index i;
757  for(i = 0; i < struc_molecule.size(); i++) {
758  if(struc_molecule[i].is_vacancy()) {
759  // set to zero, so the Va concentration is reported as 0.0
760  num_each_molecule[i] = 0;
761  }
762  num_atoms += num_each_molecule[i];
763  }
764 
765  // calculate the comp (not including vacancies) from the number of each molecule
767  for(i = 0; i < num_each_molecule.size(); i++)
768  comp.push_back((1.0 * num_each_molecule[i]) / double(num_atoms));
769 
770  return comp;
771 
772  }
773 
774  //*********************************************************************************
778 
779  Array<int> num_each_molecule = get_num_each_molecule();
780 
781  // calculate the true_comp (including vacancies) from the number of each molecule
783  for(Index i = 0; i < num_each_molecule.size(); i++)
784  comp.push_back((1.0 * num_each_molecule[i]) / size());
785 
786  return comp;
787  }
788 
789  //*********************************************************************************
793  }
794 
795  //*********************************************************************************
798  if(!get_primclex().has_composition_axes()) {
799  std::cerr << "Error in Configuration::get_param_composition()" << std::endl;
800  std::cerr << " Composition axes are not set." << std::endl;
801  exit(1);
802  }
803 
805  }
806 
807  //*********************************************************************************
811 
812  // component order used for param_composition
813  std::vector<std::string> v_components = get_primclex().composition_axes().components();
814 
815  // copy to CASM::Array
816  std::vector<std::string> components;
817  for(auto it = v_components.cbegin(); it != v_components.cend(); ++it) {
818  components.push_back(*it);
819  }
820 
821  // initialize
822  Eigen::VectorXd num_each_component = Eigen::VectorXd::Zero(components.size());
823 
824  // [basis_site][site_occupant_index]
825  auto convert = get_index_converter(get_prim(), components);
826 
827  // count the number of each component
828  for(Index i = 0; i < size(); i++) {
829  num_each_component[ convert[ get_b(i) ][occ(i)] ] += 1.0;
830  }
831 
832  // normalize per prim cell
833  for(Index i = 0; i < components.size(); i++) {
834  num_each_component[i] /= get_supercell().volume();
835  }
836 
837  return num_each_component;
838  }
839 
840 
841 
842  //********* IO ************
843 
844 
859 
860  //std::cout << "begin Configuration::write()" << std::endl;
861 
863  std::string calc_string = "calctype." + set.default_clex().calctype;
864  std::string ref_string = "ref." + set.default_clex().ref;
865 
867  jsonParser &json_scel = json["supercells"][get_supercell().get_name()];
868  jsonParser &json_config = json_scel[get_id()];
869  jsonParser &json_ref = json_config[calc_string][ref_string];
870  jsonParser &json_prop = json_ref["properties"];
871 
872  json_config["selected"] = selected();
873 
874  if(!json_config.contains("dof")) {
875  write_dof(json_config);
876  }
877 
878  if(source_updated) {
879  write_source(json_config);
880  }
881 
882  if(prop_updated) {
883  write_properties(json_prop);
884  }
885 
886  //std::cout << "finish Configuration::write()" << std::endl;
887 
888  return json;
889  }
890 
891  //*********************************************************************************
892 
894 
895  try {
896  fs::create_directories(get_path());
897  }
898  catch(const fs::filesystem_error &ex) {
899  std::cerr << "Error in Configuration::write_pos()." << std::endl;
900  std::cerr << ex.what() << std::endl;
901  }
902 
903  fs::ofstream file(get_pos_path());
904  VaspIO::PrintPOSCAR p(*this);
905  p.sort();
906  p.print(file);
907  return;
908  }
909 
910  //*********************************************************************************
911 
912  void Configuration::print_occupation(std::ostream &stream) const {
913  stream << occupation() << "\n";
914  return;
915  }
916 
917  //*********************************************************************************
918 
919  void Configuration::print_config_list(std::ostream &stream, int composition_flag) const {
920 
921  stream.width(10);
922  stream.flags(std::ios::left);
923  stream << id << " ";
924 
925  stream.width(10);
926  stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::left);
927  stream << name() << " ";
928  //Prints composition if comp_flag=1, true_composition if comp_flag=2
929  // and the sublattice composition if comp_flag=3
930  if(composition_flag == 1) {
931  print_composition(stream);
932  }
933  else if(composition_flag == 2) {
934  print_true_composition(stream);
935  }
936  else if(composition_flag == 3) {
938  }
939 
940  stream.width(8);
941  stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
942  stream << selected();
943 
944  stream << "\n";
945  }
946 
947  //*********************************************************************************
948  void Configuration::print_composition(std::ostream &stream) const {
949 
951  auto mol_list = get_prim().get_struc_molecule();
952 
953  for(Index i = 0; i < mol_list.size(); i++) {
954  if(mol_list[i].is_vacancy()) {
955  continue;
956  }
957  stream.precision(6);
958  stream.width(12);
959  stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
960  stream << comp[i] << " ";
961  }
962 
963  }
964 
965  //*********************************************************************************
966  void Configuration::print_true_composition(std::ostream &stream) const {
967 
968  Array<double> true_comp = get_true_composition();
969 
970  for(Index i = 0; i < true_comp.size(); i++) {
971  stream.precision(6);
972  stream.width(12);
973  stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
974  stream << true_comp[i] << " ";
975  }
976 
977  }
978 
979  //*********************************************************************************
980  void Configuration::print_sublattice_composition(std::ostream &stream) const {
981 
982  Array< Array<double> > sublattice_composition = get_sublattice_composition();
983 
984  for(Index i = 0; i < sublattice_composition.size(); i++) {
985  for(Index j = 0; j < sublattice_composition[i].size(); j++) {
986  stream.precision(6);
987  stream.width(12);
988  stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
989  stream << sublattice_composition[i][j] << " ";
990  }
991  }
992 
993  }
994 
995  //*********************************************************************************
996 
998 
1015  void Configuration::read(const jsonParser &json) {
1016 
1017  //std::cout << "begin Configuration::read()" << std::endl;
1018 
1020 
1021  std::string calc_string = "calctype." + set.default_clex().calctype;
1022  std::string ref_string = "ref." + set.default_clex().ref;
1023 
1024  // read dof
1025  if(!json.contains("supercells"))
1026  return;
1027  const jsonParser &json_scel = json["supercells"];
1028  if(!json_scel.contains(get_supercell().get_name()))
1029  return;
1030  if(!json_scel[get_supercell().get_name()].contains(get_id()))
1031  return;
1032  const jsonParser &json_config = json_scel[get_supercell().get_name()][get_id()];
1033 
1034  read_dof(json_config);
1035 
1036 
1037  // read properties: does not attempt to read in new calculation data
1038  if(!json_config.contains(calc_string))
1039  return;
1040  const jsonParser &json_calc = json_config[calc_string];
1041  if(!json_calc.contains(ref_string))
1042  return;
1043  const jsonParser &json_ref = json_calc[ref_string];
1044  if(!json_ref.contains("properties"))
1045  return;
1046  const jsonParser &json_prop = json_ref["properties"];
1047 
1048  read_properties(json_prop);
1049 
1050  //std::cout << "finish Configuration::read()" << std::endl;
1051  }
1052 
1053  //*********************************************************************************
1054 
1067 
1069  if(!json.contains("dof")) {
1070  _invalidate_id();
1071  set_selected(false);
1072  return;
1073  }
1074  else {
1075 
1076  json.get_if(m_source, "source");
1077  json.get_else(m_selected, "selected", false);
1078  from_json(m_configdof, json["dof"]);
1079  }
1080  }
1081 
1082  //*********************************************************************************
1094  if(json.contains("calc")) {
1095  from_json(calculated, json["calc"]);
1096  }
1097 
1098  if(json.contains("gen")) {
1099  from_json(generated, json["gen"]);
1100  }
1101  }
1102 
1103  //*********************************************************************************
1105  return get_primclex().dir().POS(name());
1106  }
1107 
1108  //*********************************************************************************
1110  return get_primclex().dir().configuration_calc_dir(name(), get_primclex().settings().default_clex().calctype);
1111  }
1112 
1113  //*********************************************************************************
1115  return get_primclex().dir().calculated_properties(name(), get_primclex().settings().default_clex().calctype);
1116  }
1117 
1118  //*********************************************************************************
1120  return get_primclex().dir().calc_status(name(), get_primclex().settings().default_clex().calctype);
1121  }
1122 
1123  //*********************************************************************************
1132 
1133  if(!json["dof"].is_obj()) {
1134  json["dof"].put_obj();
1135  }
1136 
1137  jsonParser &dof = json["dof"];
1138 
1139  if(occupation().size() == 0) {
1140  dof.erase("occupation");
1141  }
1142  else {
1143  dof["occupation"] = occupation();
1144  }
1145 
1146  if(displacement().size() == 0) {
1147  dof.erase("displacement");
1148  }
1149  else {
1150  dof["displacement"] = displacement();
1151  }
1152 
1153  if(!has_deformation()) {
1154  dof.erase("deformation");
1155  }
1156  else {
1157  dof["deformation"] = deformation();
1158  }
1159 
1160  return json;
1161 
1162  }
1163 
1164  //*********************************************************************************
1169 
1170  json["source"] = m_source;
1171 
1172  return json;
1173 
1174  }
1175 
1176  //*********************************************************************************
1182 
1183  // print POS to stringstream
1184  if(occupation() != get_supercell().vacant()) {
1185  std::stringstream ss;
1186  VaspIO::PrintPOSCAR p(*this);
1187  p.sort();
1188  p.print(ss);
1189 
1190  json["pos"] = ss.str();
1191  }
1192  else {
1193  json["pos"].put_null();
1194  }
1195 
1196  return json;
1197 
1198  }
1199 
1200  //*********************************************************************************
1205 
1206  if(!get_primclex().has_composition_axes()) {
1207  json.erase("param_comp_formula");
1208  json.erase("param_composition");
1209  return json;
1210  }
1211 
1212  json["param_comp_formula"] = get_primclex().composition_axes().mol_formula();
1213  json["param_composition"] = get_param_composition();
1214 
1215  return json;
1216 
1217  }
1218 
1219  //*********************************************************************************
1224 
1225  if(calculated.size() == 0) {
1226  json.erase("calc");
1227  }
1228  else {
1229  json["calc"] = calculated;
1230  }
1231 
1232  if(generated.size() == 0) {
1233  json.erase("gen");
1234  }
1235  else {
1236  json["gen"] = generated;
1237  }
1238 
1239  return json;
1240 
1241  }
1242 
1243  //*********************************************************************************
1244  //--------------------------------------------------------------------------------------------------
1245  //Structure Factor
1247  Eigen::VectorXd automatic_intensities(get_prim().get_struc_molecule().size());
1248  for(int i = 0; i < get_prim().get_struc_molecule().size(); i++)
1249  automatic_intensities(i) = i;
1250  return get_struct_fact_intensities(automatic_intensities);
1251  }
1252 
1254  auto convert = get_index_converter(get_prim(), get_prim().get_struc_molecule());
1255  Eigen::VectorXd intensities(size());
1256  for(int i = 0; i < size(); i++) {
1257  intensities(i) = component_intensities(convert[get_b(i)][occ(i)]);
1258  }
1259  return intensities;
1260  }
1261 
1270  //std::cout<<"Intensities"<<std::endl<<intensities<<std::endl;
1271  Eigen::MatrixXcd sublat_sf(supercell->basis_size(), supercell->fourier_matrix().cols());
1272  if(supercell->fourier_matrix().rows() == 0 || supercell->fourier_matrix().cols() == 0) {
1273  std::cerr << "ERROR in Configuration::calc_sublat_struct_fact. Did you "
1274  << "forget to initialize a fourier matrix in Supercell?"
1275  << " Quitting" << std::endl;
1276  exit(666);
1277  }
1278  //int num_kpoints = supercell->fourier_matrix().cols();
1279  int supercell_volume = supercell->volume();
1280  for(int i = 0; i < supercell->basis_size(); i++) {
1281  Eigen::VectorXd int_segment = intensities.segment(i * supercell_volume, supercell_volume);
1282  // std::cout<<"Intensity segment:"<<int_segment.transpose()<<std::endl;
1283  // std::cout<<"Fourier:"<<std::endl<<supercell->fourier_matrix()<<std::endl;
1284  sublat_sf.row(i) = int_segment.transpose() * supercell->fourier_matrix();
1285  }
1286  sublat_sf = sublat_sf / double(supercell->volume());
1287  // std::cout<<"Sublattice struct factor:"<<std::endl;
1288  // std::cout<<sublat_sf.transpose()<<std::endl;
1289  generated["sublat_struct_fact"] = sublat_sf.transpose();
1290  prop_updated = true;
1291  }
1292 
1302  if(supercell->phase_factor().rows() == 0 || supercell->phase_factor().cols() == 0) {
1303  std::cerr << "ERROR in Configuration::calc_struct_fact. Did you "
1304  << "forget to initialize a phase-factor matrix in Supercell?"
1305  << " Quitting" << std::endl;
1306  exit(666);
1307  }
1308  calc_sublat_struct_fact(intensities);
1309  Eigen::MatrixXcd sublat_sf = generated["sublat_struct_fact"].get<Eigen::MatrixXcd>();
1310  // std::cout<<"Multiplication matrix:"<<std::endl<<sublat_sf*supercell->phase_factor()<<std::endl;
1311  Eigen::VectorXcd raw_amplitudes = (sublat_sf * supercell->phase_factor()).diagonal();
1312  // std::cout.precision(4);
1313  // std::cout<<std::fixed;
1314  // std::cout<<"Raw amplitudes:"<<std::endl<<raw_amplitudes.transpose()<<std::endl;
1315  Eigen::MatrixXd sf_coords(raw_amplitudes.size(), 4);
1316  sf_coords.leftCols(3) = supercell->k_mesh();
1317  sf_coords.col(3) = raw_amplitudes.cwiseAbs().transpose() / double(supercell->basis_size());
1318  generated["struct_fact"] = sf_coords;
1319  prop_updated = true;
1320  }
1321 
1324  }
1325 
1328  }
1329 
1331  if(!generated.contains("struct_fact"))
1332  calc_struct_fact();
1333  return generated["struct_fact"].get<Eigen::MatrixXd>();
1334  }
1335 
1337  if(!generated.contains("sublat_struct_fact"))
1339  return generated["sublat_struct_fact"].get<Eigen::MatrixXcd>();
1340  }
1341 
1343  return this->canonical_form() == B.canonical_form();
1344  }
1345 
1347  if(get_supercell() != B.get_supercell()) {
1348  return get_supercell() < B.get_supercell();
1349  }
1350  ConfigCompare f(*this, crystallography_tol());
1351  return f(B);
1352  }
1353 
1354  std::pair<std::string, Index> Configuration::split_name(std::string configname) {
1355  std::vector<std::string> splt_vec;
1356  boost::split(splt_vec, configname, boost::is_any_of("/"), boost::token_compress_on);
1357  Index config_ind;
1358  if(splt_vec.size() != 2) {
1359  default_err_log().error("Parsing configuration name");
1360  default_err_log() << "configuration '" << configname << "' not valid." << std::endl;
1361  throw std::invalid_argument("Error in Configuration::split_name(const std::string &configname) const: Not valid");
1362  }
1363 
1364  try {
1365  config_ind = boost::lexical_cast<Index>(splt_vec[1]);
1366  }
1367  catch(boost::bad_lexical_cast &e) {
1368  default_err_log().error("Invalid config index");
1369  default_err_log() << "CRITICAL ERROR: In PrimClex::configuration(), malformed input:" << configname << "\n";
1370  throw e;
1371  }
1372  return std::make_pair(splt_vec[0], config_ind);
1373  }
1374 
1375  bool Configuration::_eq(const Configuration &B) const {
1376  if(get_supercell() != B.get_supercell()) {
1377  return false;
1378  }
1380  return f(B);
1381  }
1382 
1384  apply(it, config.configdof());
1385  return config;
1386  }
1387 
1398  Supercell &sub_scel,
1399  const Configuration &super_config,
1400  const UnitCell &origin) {
1401 
1402  //std::cout << "begin sub_configuration" << std::endl;
1403  if(&sub_scel.get_primclex() != &super_config.get_primclex()) {
1404  throw std::runtime_error(std::string("Error in 'sub_configuration:"
1405  " PrimClex of sub-Supercell and super-configuration are not the same"));
1406  }
1407 
1408  //std::cout << " here 1" << std::endl;
1409  Configuration sub_config {sub_scel};
1410 
1411  //std::cout << " here 2" << std::endl;
1412  // copy global dof
1413  if(super_config.has_deformation()) {
1414  sub_config.configdof().set_deformation(super_config.deformation());
1415  }
1416 
1417 
1418  //std::cout << " here 3" << std::endl;
1419  // initialize site dof
1420  if(super_config.has_occupation()) {
1421  sub_config.configdof().set_occupation(Array<int>(sub_config.size(), 0));
1422  }
1423  if(super_config.has_displacement()) {
1424  sub_config.configdof().set_displacement(
1425  ConfigDoF::displacement_matrix_t::Zero(3, sub_config.size()));
1426  }
1427 
1428  //std::cout << " here 4" << std::endl;
1429  // copy site dof
1430  for(Index i = 0; i < sub_config.size(); i++) {
1431 
1432  // unitcell of site i in sub_config
1433  UnitCellCoord unitcellcoord = sub_config.get_uccoord(i);
1434 
1435  // equivalent site in superconfig
1436  Index site_index = super_config.get_supercell().find(unitcellcoord + origin);
1437 
1438  // copy dof from superconfig to this:
1439 
1440  // occupation
1441  sub_config.configdof().occ(i) = super_config.occ(site_index);
1442 
1443  // displacement
1444  if(super_config.has_displacement()) {
1445  sub_config.configdof().disp(i) = super_config.disp(site_index);
1446  }
1447 
1448  }
1449 
1450  //std::cout << "finish sub_configuration" << std::endl;
1451  return sub_config;
1452  }
1453 
1454 
1455  namespace {
1456  std::vector<std::string> split(std::string s, char delim) {
1457  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
1458  boost::char_separator<char> sep(&delim);
1459  tokenizer tok(s, sep);
1460  return std::vector<std::string>(tok.begin(), tok.end());
1461  }
1462  }
1463 
1483 
1484  // if $CANON_SCELNAME.$PRIM_FG_OP1/super.$PRIM_FG_OP2.$PRIMSCELNAME/$PRIM_CANON_INDEX.equiv.$FG_PERM.$TRANS_PERM
1485  auto pos = name.find("super");
1486  if(name.find("super") != std::string::npos) {
1487  std::string format = "$CANON_SCELNAME.$PRIM_FG_OP1/super.$PRIM_FG_OP2."
1488  "$PRIM_SCELNAME/$PRIM_CANON_INDEX"
1489  ".equiv.$FG_PERM.$TRANS_PERM";
1490 
1491  std::vector<std::string> tokens = split(name, '.');
1492  if(tokens.size() != 7) {
1493  primclex.err_log().error("In make_configuration");
1494  primclex.err_log() << "expected format: " << format << "\n";
1495  primclex.err_log() << "name: " << name << std::endl;
1496  primclex.err_log() << "tokens: " << tokens << std::endl;
1497  throw std::invalid_argument("Error in make_configuration: configuration name format error");
1498  }
1499 
1500  // prim equiv name
1501  Configuration prim_equiv = make_configuration(
1502  primclex,
1503  name.substr(pos + std::string("super").size() + 1));
1504 
1505  std::string scelname = name.substr(0, pos - 1);
1506  Index fg_op_index = boost::lexical_cast<Index>(tokens[1]);
1507  const auto &sym_op = primclex.get_prim().factor_group()[fg_op_index];
1508 
1509  if(sym_op.index() != fg_op_index) {
1510  primclex.err_log().error("In make_configuration");
1511  primclex.err_log() << "expected format: " << format << "\n";
1512  primclex.err_log() << "name: " << name << std::endl;
1513  primclex.err_log() << "read fg_op_index: " << fg_op_index << std::endl;
1514  primclex.err_log() << "primclex.get_prim().factor_group()[fg_op_index].index(): "
1515  << primclex.get_prim().factor_group()[fg_op_index].index()
1516  << std::endl << std::endl;
1517  throw std::runtime_error("Error in make_configuration: PRIM_FG_OP index mismatch");
1518  }
1519 
1520  FillSupercell f(
1521  primclex.get_supercell(scelname),
1522  sym_op);
1523 
1524  return f(prim_equiv);
1525  }
1526 
1527  // if $PRIM_SCELNAME/$PRIM_CANON_INDEX.equiv.$FG_PERM.$TRANS_PERM
1528  pos = name.find("equiv");
1529  if(pos != std::string::npos) {
1530 
1531  std::string format = "$PRIM_SCELNAME/$PRIM_CANON_INDEX"
1532  ".equiv.$FG_PERM.$TRANS_PERM";
1533 
1534  //split $PRIM_SCELNAME/$PRIM_CANON_INDEX & $FG_PERM & $TRANS_PERM
1535  std::vector<std::string> tokens = split(name, '.');
1536  std::string primname = tokens[0];
1537  if(tokens.size() != 4) {
1538  primclex.err_log().error("In make_configuration");
1539  primclex.err_log() << "expected format: " << format << "\n";
1540  primclex.err_log() << "name: " << name << std::endl;
1541  primclex.err_log() << "tokens: " << tokens << std::endl;
1542  throw std::invalid_argument("Error in make_configuration: configuration name format error");
1543  }
1544 
1545  Configuration pconfig = primclex.configuration(primname);
1546  Index fg_index = boost::lexical_cast<Index>(tokens[2]);
1547  Index trans_index = boost::lexical_cast<Index>(tokens[3]);
1548 
1549  return apply(pconfig.get_supercell().permute_it(fg_index, trans_index), pconfig);
1550  }
1551 
1552  // if $CANON_SCELNAME/$CANON_INDEX
1553  return primclex.configuration(name);
1554  }
1555 
1557  Correlation correlations(const Configuration &config, Clexulator &clexulator) {
1558  return correlations(config.configdof(), config.get_supercell(), clexulator);
1559  }
1560 
1563  return config.get_param_composition();
1564  }
1565 
1568  return config.get_num_each_component();
1569  }
1570 
1572  double n_vacancy(const Configuration &config) {
1573  if(config.get_primclex().vacancy_allowed()) {
1574  return comp_n(config)[config.get_primclex().vacancy_index()];
1575  }
1576  return 0.0;
1577  }
1578 
1582  double n_species(const Configuration &config) {
1583  return comp_n(config).sum() - n_vacancy(config);
1584  }
1585 
1590  Eigen::VectorXd v = comp_n(config);
1591  if(config.get_primclex().vacancy_allowed()) {
1592  v(config.get_primclex().vacancy_index()) = 0.0;
1593  }
1594  return v / v.sum();
1595  }
1596 
1599  return comp_n(config) / config.get_prim().basis.size();
1600  }
1601 
1603  double relaxed_energy(const Configuration &config) {
1604  return config.calc_properties()["relaxed_energy"].get<double>();
1605  }
1606 
1609  return relaxed_energy(config) / n_species(config);
1610  }
1611 
1613  double reference_energy(const Configuration &config) {
1614  return reference_energy_per_species(config) * n_species(config);
1615  }
1616 
1621  return config.get_primclex().chemical_reference()(config);
1622  }
1623 
1625  double formation_energy(const Configuration &config) {
1626  return relaxed_energy(config) - reference_energy(config);
1627  }
1628 
1633  return formation_energy(config) / n_species(config);
1634  }
1635 
1637  double clex_formation_energy(const Configuration &config) {
1638  const auto &primclex = config.get_primclex();
1639  auto formation_energy = primclex.settings().clex("formation_energy");
1642 
1643  if(eci.index().back() >= clexulator.corr_size()) {
1645  err_log.error<Log::standard>("bset and eci mismatch");
1646  err_log << "using cluster expansion: 'formation_energy'" << std::endl;
1647  err_log << "basis set size: " << clexulator.corr_size() << std::endl;
1648  err_log << "max eci index: " << eci.index().back() << std::endl;
1649  throw std::runtime_error("Error: bset and eci mismatch");
1650  }
1651 
1652  return eci * correlations(config, clexulator);
1653  }
1654 
1657  return clex_formation_energy(config) / n_species(config);
1658  }
1659 
1661  bool is_calculated(const Configuration &config) {
1662  const auto &set = config.get_primclex().settings();
1663  return std::all_of(set.properties().begin(),
1664  set.properties().end(),
1665  [&](const std::string & key) {
1666  return config.calc_properties().contains(key);
1667  });
1668  }
1669 
1671  double rms_force(const Configuration &_config) {
1672  return _config.calc_properties()["rms_force"].get<double>();
1673  }
1674 
1676  double basis_deformation(const Configuration &_config) {
1677  return _config.calc_properties()["basis_deformation"].get<double>();
1678  }
1679 
1681  double lattice_deformation(const Configuration &_config) {
1682  return _config.calc_properties()["lattice_deformation"].get<double>();
1683  }
1684 
1686  double volume_relaxation(const Configuration &_config) {
1687  return _config.calc_properties()["volume_relaxation"].get<double>();
1688  }
1689 
1691  double relaxed_magmom(const Configuration &_config) {
1692  return _config.calc_properties()["relaxed_magmom"].get<double>();
1693  }
1694 
1697  return relaxed_magmom(_config) / n_species(_config);
1698  }
1699 
1702  return _config.calc_properties()["relaxed_mag_basis"].get<Eigen::VectorXd>();
1703  }
1704 
1707  return _config.calc_properties()["relaxed_mag"].get<Eigen::VectorXd>();
1708  }
1709 
1711  bool is_primitive(const Configuration &_config) {
1712  return _config.is_primitive();
1713  }
1714 
1716  bool is_canonical(const Configuration &_config) {
1717  return _config.is_canonical();
1718  }
1719 
1720  bool has_relaxed_energy(const Configuration &_config) {
1721  return _config.calc_properties().contains("relaxed_energy");
1722  }
1723 
1724  bool has_reference_energy(const Configuration &_config) {
1725  return _config.get_primclex().has_composition_axes() &&
1727  }
1728 
1729  bool has_formation_energy(const Configuration &_config) {
1730  return has_relaxed_energy(_config) && has_reference_energy(_config);
1731  }
1732 
1733  bool has_rms_force(const Configuration &_config) {
1734  return _config.calc_properties().contains("rms_force");
1735  }
1736 
1737  bool has_basis_deformation(const Configuration &_config) {
1738  return _config.calc_properties().contains("basis_deformation");
1739  }
1740 
1742  return _config.calc_properties().contains("lattice_deformation");
1743  }
1744 
1745  bool has_volume_relaxation(const Configuration &_config) {
1746  return _config.calc_properties().contains("volume_relaxation");
1747  }
1748 
1749  bool has_relaxed_magmom(const Configuration &_config) {
1750  return _config.calc_properties().contains("relaxed_magmom");
1751  }
1752 
1753  bool has_relaxed_mag_basis(const Configuration &_config) {
1754  return _config.calc_properties().contains("relaxed_mag_basis");
1755  }
1756 
1763  m_scel(&_scel), m_op(&_op), m_motif_scel(nullptr) {}
1764 
1772  FillSupercell::FillSupercell(Supercell &_scel, const Configuration &_motif, double _tol) :
1773  m_scel(&_scel), m_op(find_symop(_motif, _tol)), m_motif_scel(nullptr) {}
1774 
1776 
1777  if(&motif.get_supercell() != m_motif_scel) {
1778  _init(motif.get_supercell());
1779  }
1780 
1781  Configuration result(*m_scel);
1782 
1783  // ------- global dof ----------
1784  if(motif.has_deformation()) {
1785  result.set_deformation(m_op->matrix()*motif.deformation()*m_op->matrix().transpose());
1786  }
1787 
1788  // ------- site dof ----------
1789  Array<int> tscel_occ;
1790  ConfigDoF::displacement_matrix_t tscel_disp, motif_new_disp;
1791 
1792  // apply fg op
1793  if(motif.has_occupation()) {
1794  result.set_occupation(Array<int>(m_scel->num_sites(), 0));
1795  }
1796  //std::cout << "has_disp: " << motif.has_displacement() << std::endl;
1797  if(motif.has_displacement()) {
1798  result.init_displacement();
1799  //std::cout << "disp: " << motif.displacement() << std::endl;
1800  //std::cout << "mat: \n" << m_op->matrix() << std::endl;
1801  motif_new_disp = m_op->matrix() * motif.displacement();
1802  //std::cout << "new_disp: " << motif_new_disp << std::endl;
1803 
1804  }
1805 
1806  // copy transformed dof, as many times as necessary to fill the supercell
1807  for(Index s = 0; s < m_index_table.size(); ++s) {
1808  for(Index i = 0; i < m_index_table[s].size(); ++i) {
1809  Index scel_s = m_index_table[s][i];
1810 
1811  if(motif.has_occupation()) {
1812  result.configdof().occ(scel_s) = motif.occ(s);
1813  }
1814  if(motif.has_displacement()) {
1815  result.configdof().disp(scel_s) = motif_new_disp.col(s);
1816  }
1817  }
1818  }
1819  if(motif.has_displacement()) {
1820  //std::cout << "final disp: " << result.displacement() << std::endl;
1821  }
1822  return result;
1823  }
1824 
1827  const SymOp *FillSupercell::find_symop(const Configuration &motif, double tol) {
1828 
1829  const Lattice &motif_lat = motif.get_supercell().get_real_super_lattice();
1830  const Lattice &scel_lat = m_scel->get_real_super_lattice();
1831  auto begin = m_scel->get_primclex().get_prim().factor_group().begin();
1832  auto end = m_scel->get_primclex().get_prim().factor_group().end();
1833 
1834  auto res = is_supercell(scel_lat, motif_lat, begin, end, tol);
1835  if(res.first == end) {
1836 
1837  std::cerr << "Requested supercell transformation matrix: \n"
1838  << m_scel->get_transf_mat() << "\n";
1839  std::cerr << "Requested motif Configuration: "
1840  << motif.name() << "\n";
1841  std::cerr << "Configuration transformation matrix: \n"
1842  << motif.get_supercell().get_transf_mat() << "\n";
1843 
1844  throw std::runtime_error(
1845  "Error in 'FillSupercell::find_symop':\n"
1846  " The motif cannot be tiled onto the specified supercell."
1847  );
1848  }
1849 
1850  return &(*res.first);
1851  }
1852 
1853  void FillSupercell::_init(Supercell &_motif_scel) const {
1854 
1855  m_motif_scel = &_motif_scel;
1856 
1857  // ------- site dof ----------
1858  Lattice oriented_motif_lat = copy_apply(*m_op, m_motif_scel->get_real_super_lattice());
1859 
1860  // Create a PrimGrid linking the prim and the oriented motif each to the supercell
1861  // So we can tile the decoration of the motif config onto the supercell correctly
1862  PrimGrid prim_grid(oriented_motif_lat, m_scel->get_real_super_lattice());
1863 
1864  //std::cout << "m_op->matrix(): \n" << m_op->matrix() << std::endl;
1865  //std::cout << "m_op->tau(): \n" << m_op->tau() << std::endl;
1866 
1867  const Structure &prim = m_scel->get_prim();
1869 
1870  // for each site in motif
1871  for(Index s = 0 ; s < m_motif_scel->num_sites() ; s++) {
1872 
1873  //std::cout << "before: " << m_motif_scel->uccoord(s) << std::endl;
1874 
1875  // apply symmetry to re-orient and find unit cell coord
1876  UnitCellCoord oriented_uccoord = copy_apply(*m_op, m_motif_scel->uccoord(s), prim);
1877  //std::cout << "after: " << oriented_uccoord << std::endl;
1878 
1879  // for each unit cell of the oriented motif in the supercell, copy the occupation
1880  for(Index i = 0 ; i < prim_grid.size() ; i++) {
1881 
1882  Index prim_motif_tile_ind = m_scel->prim_grid().find(prim_grid.coord(i, PRIM));
1883 
1884  UnitCellCoord mc_uccoord = m_scel->prim_grid().uccoord(prim_motif_tile_ind) + oriented_uccoord.unitcell();
1885  // b-index when doing UnitCellCoord addition is ambiguous; explicitly set it
1886  mc_uccoord.sublat() = oriented_uccoord.sublat();
1887 
1888  m_index_table[s].push_back(m_scel->find(mc_uccoord));
1889  }
1890  }
1891 
1892  }
1893 
1894  std::ostream &operator<<(std::ostream &sout, const Configuration &c) {
1895 
1896  sout << c.name() << "\n";
1897  if(c.has_deformation()) {
1898  sout << "Deformation:\n" << c.deformation() << std::endl;
1899  }
1900  for(Index i = 0; i < c.size(); ++i) {
1901  sout << "Linear index: " << i << " UnitCellCoord: " << c.get_uccoord(i) << std::endl;
1902  if(c.has_occupation()) {
1903  sout << " Occupation: " << c.occ(i) << " (" << c.get_mol(i).name << ")\n";
1904  }
1905  if(c.has_displacement()) {
1906  sout << " Displacement: " << c.disp(i).transpose() << "\n";
1907  }
1908  }
1909  return sout;
1910  }
1911 
1912 }
1913 
1914 
Eigen::MatrixXd MatrixXd
const PrimGrid & prim_grid() const
Definition: Supercell.hh:205
void clear_deformation()
Clear applied strain.
Clexulator clexulator(const ClexDescription &key) const
Definition: PrimClex.cc:1030
void clear_displacement()
Clear displacement.
pair_type eci
Definition: settings.cc:112
size_type size() const
Returns array size if *this is a JSON array, object size if *this is a JSON object, 1 otherwise.
Definition: jsonParser.cc:430
bool insert_primitive
True if primitive did not exist before insertion.
Configuration fill_supercell(Supercell &scel, const SymOp &op) const
Fills supercell 'scel' with reoriented configuration, as if by apply(op,*this)
ConfigInsertResult insert(bool primitive_only) const
Insert this in the canonical Supercell.
std::string get_name() const
Return supercell name.
Definition: Supercell.cc:123
double rms_force(const Configuration &_config)
Root-mean-square forces of relaxed configurations, determined from DFT (eV/Angstr.)
Eigen::VectorXd get_param_composition() const
Returns parametric composition, as calculated using PrimClex::param_comp.
const_displacement_t disp(Index site_l) const
Occupant displacement.
bool selected() const
True if this Configuration is currently selected in the MASTER config list.
static std::pair< std::string, Index > split_name(std::string configname)
Split configuration name string into scelname and config index.
int & occ(Index i)
Definition: ConfigDoF.hh:61
Eigen::MatrixXcd sublat_struct_fact()
void init_occupation()
Set occupant variables to background structure.
static const std::string name
ReturnArray< int > get_num_each_molecule(const ConfigDoF &configdof, const Supercell &scel)
Returns num_each_molecule[ molecule_type], where 'molecule_type' is ordered as Structure::get_struc_m...
Definition: ConfigDoF.cc:278
void from_json(ClexDescription &desc, const jsonParser &json)
UnitCellCoord get_uccoord(Index site_l) const
Get the UnitCellCoord for a given linear site index.
void set_displacement(const displacement_matrix_t &_displacement)
Definition: ConfigDoF.cc:102
Eigen::VectorXd relaxed_mag(const Configuration &_config)
Returns the relaxed magnetic moment for each molecule.
const int & occ(Index site_l) const
Occupant variable on site l.
Index size() const
Definition: Array.hh:145
Supercell * supercell
const pointer to the (non-const) Supercell for this Configuration
void set_deformation(const Eigen::Matrix3d &_deformation)
Set applied strain.
PrimClex & get_primclex() const
Get the PrimClex for this Configuration.
double relaxed_magmom(const Configuration &_config)
Returns the relaxed magnetic moment, normalized per unit cell.
void read_dof(const jsonParser &json)
Functions used to perform read()
void read_properties(const jsonParser &json)
const Molecule & get_mol(Index site_l) const
Molecule on site l.
const Eigen::MatrixXcd & fourier_matrix() const
Definition: Supercell.hh:229
Eigen::VectorXd param_composition(const Eigen::VectorXd &n) const
Convert number of mol per prim, 'n' to parametric composition 'x'.
const DirectoryStructure & dir() const
Definition: PrimClex.hh:112
std::string calc_status() const
bool has_basis_deformation(const Configuration &_config)
bool is_vacancy(const std::string &name)
A vacancy is any Specie/Molecule with (name == "VA" || name == "va" || name == "Va") ...
Definition: Molecule.hh:27
bool get_if(T &t, const std::string &key, Args...args) const
Definition: jsonParser.hh:740
void push_back(const T &toPush)
Definition: Array.hh:513
bool is_equivalent(const Configuration &B) const
Check if Configuration are equivalent wrt the prim's factor group.
const Structure & get_prim() const
Definition: Supercell.cc:74
const Array< int > & occupation() const
Occupant variables.
bool has_formation_energy(const Configuration &_config)
Structure specifies the lattice and atomic basis of a crystal.
Definition: Structure.hh:29
Configuration make_configuration(PrimClex &primclex, std::string name)
Make Configuration from name string.
PrimClex * primclex
Definition: settings.cc:101
Object copy_apply(const Transform &f, Object obj, Args &&...args)
fs::path calc_properties_path() const
config_const_iterator primitive_it
Iterator pointing at primitive.
void resize(Index new_N)
Definition: Array.hh:468
Configuration canonical_form() const
Returns the canonical form Configuration in the same Supercell.
void print_sublattice_composition(std::ostream &stream) const
std::vector< Molecule > get_struc_molecule() const
Returns an Array of each possible Molecule in this Structure.
Definition: Structure.cc:146
fs::path calculated_properties(std::string configname, std::string calctype) const
Return calculated properties file path.
Eigen::MatrixXd struct_fact()
void print_occupation(std::ostream &stream) const
Unit Cell Coordinates.
bool has_composition_axes() const
check if CompositionConverter object initialized
Definition: PrimClex.cc:231
bool has_lattice_deformation(const Configuration &_config)
Correlation correlations(const ConfigDoF &configdof, const Supercell &scel, Clexulator &clexulator)
Returns correlations using 'clexulator'. Supercell needs a correctly populated neighbor list...
Definition: ConfigDoF.cc:200
double clex_formation_energy_per_species(const Configuration &config)
Returns the formation energy, normalized per species.
bool has_relaxed_energy(const Configuration &_config)
const jsonParser & source() const
const ConfigDoF & configdof() const
const Access the DoF
void push_back_source(const jsonParser &source)
config_const_iterator canonical_it
Iterator pointing at canonical, if existing.
const Lattice & get_real_super_lattice() const
Definition: Supercell.hh:267
const Eigen::MatrixXd & k_mesh() const
Definition: Supercell.hh:237
Eigen::VectorXd get_num_each_component() const
ConfigDoF m_configdof
Degrees of Freedom.
PermuteIterator inverse() const
void print_true_composition(std::ostream &stream) const
void set_displacement(const displacement_matrix_t &_disp)
Set occupant displacements.
size_type corr_size() const
Number of correlations.
Definition: Clexulator.hh:370
double n_species(const Configuration &config)
Returns the total number species per unit cell.
Lattice get_reduced_cell() const
Find the lattice vectors which give most compact unit cell Compactness is measured by how close lat_c...
Definition: Lattice.cc:442
Supercell & canonical_form() const
Definition: Supercell.cc:910
int get_b(Index site_l) const
Get the basis site index for a given linear linear site index.
fs::path calc_status_path() const
Configuration primitive() const
Return the primitive Configuration.
fs::path configuration_calc_dir(std::string configname, std::string calctype) const
Return calculated properties file path.
Main CASM namespace.
Definition: complete.cpp:8
void set_disp(Index site_l, const Eigen::VectorXd &_disp)
Set occupant displacements.
std::string mol_formula() const
Return formula for x->n.
Eigen::VectorXd comp(const Configuration &config)
Returns parametric composition, as calculated using PrimClex::param_comp.
const Lattice & ideal_lattice() const
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:37
jsonParser m_source
a jsonParser object indicating where this Configuration came from
Unit Cell Indices.
std::string m_name
Remember name.
const Properties & generated_properties() const
ReturnArray< Array< int > > get_sublat_num_each_molecule() const
displacement_t _disp(Index site_l)
PrimClex & get_primclex() const
Definition: Supercell.hh:201
fs::path calc_dir() const
ProjectSettings & set
Definition: settings.cc:103
Index basis_size() const
Definition: Supercell.hh:216
Index find(const Coordinate &_coord) const
Definition: PrimGrid.cc:144
T get(Args...args) const
Get data from json, using one of several alternatives.
Definition: jsonParser.hh:729
Configuration operator()(const Configuration &motif) const
bool read_calc_properties(jsonParser &parsed_props) const
double relaxed_energy_per_species(const Configuration &config)
Returns the relaxed energy, normalized per species.
std::vector< std::string > get_struc_molecule_name() const
Returns an Array of each possible Molecule in this Structure.
Definition: Structure.cc:166
Eigen::VectorXd get_struct_fact_intensities() const
bool has_chemical_reference() const
check if ChemicalReference object initialized
Definition: PrimClex.cc:245
bool insert_canonical
True if canonical configuration did not exist before insertion.
void print(std::ostream &sout)
Print POSCAR to stream.
Definition: VaspIO.hh:509
fs::path get_path() const
Return path to supercell directory.
Definition: Supercell.cc:865
const Structure & get_prim() const
Get the primitive Structure for this Configuration.
ConfigIterator< const Configuration, const PrimClex > config_const_iterator
Definition: PrimClex.hh:86
bool vacancy_allowed() const
returns true if vacancy are an allowed species
Definition: PrimClex.cc:284
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:33
std::vector< std::string > components() const
The order of components in mol composition vectors.
std::string get_id() const
bool _eq(const Configuration &B) const
Equality comparison of Configuration, via ConfigEqual.
Supercell * m_motif_scel
Eigen::VectorXd comp_n(const ConfigDoF &configdof, const Supercell &scel)
Returns comp_n, the number of each molecule per primitive cell, ordered as Structure::get_struc_molec...
Definition: ConfigDoF.cc:312
double tol
void _init(Supercell &_motif_scel) const
jsonParser & put_null()
Puts 'null' JSON value.
Definition: jsonParser.hh:305
const matrix_type & matrix() const
Const access of entire cartesian symmetry matrix.
Definition: SymOp.hh:57
bool has_occupation() const
True if Configuration has occupation DoF.
double formation_energy(const Configuration &config)
Returns the formation energy, normalized per unit cell.
double clex_formation_energy(const Configuration &config)
Returns the formation energy, normalized per unit cell.
const std::vector< std::string > & properties() const
Get current properties.
const ClexDescription & clex(std::string name) const
bool is_canonical() const
Check if Configuration is in the canonical form.
const Properties & calc_properties() const
permute_const_iterator permute_begin() const
Definition: Supercell.cc:179
bool is_null() const
Check if null type.
Definition: jsonParser.cc:251
size_type erase(const std::string &name)
Erase key:value pair from an object.
Definition: jsonParser.cc:506
std::ostream & operator<<(std::ostream &_stream, const FormattedPrintable &_formatted)
static const int standard
Definition: Log.hh:15
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
void print_composition(std::ostream &stream) const
const MasterSymGroup & factor_group() const
Definition: Structure.cc:94
fs::path get_pos_path() const
Path to various files.
Read/modify settings of an already existing CASM project.
Class for less than comparison of Configurations (with the same Supercell)
std::vector< std::vector< Index > > m_index_table
bool has_relaxed_mag_basis(const Configuration &_config)
EigenIndex Index
For long integer indexing:
const SymOp * m_op
void sort()
Default sort is by atom name.
Definition: VaspIO.hh:500
Index volume() const
Return number of primitive cells that fit inside of *this.
Definition: Supercell.hh:212
Evaluates correlations.
Definition: Clexulator.hh:240
bool has_rms_force(const Configuration &_config)
void set_occupation(const Array< int > &newoccupation)
Set occupant variables.
bool has_deformation() const
True if Configuration has strain DoF.
std::string id
Identification.
A container class for the different degrees of freedom a Configuration might have.
Definition: ConfigDoF.hh:27
pair_type calctype
Definition: settings.cc:109
ReturnArray< int > get_num_each_molecule() const
Returns num_each_molecule[ molecule_type], where 'molecule_type' is ordered as Structure::get_struc_m...
bool is_canonical(const Configuration &_config)
returns true if _config no symmetry transformation applied to _config will increase its lexicographic...
double volume_relaxation(const Configuration &_config)
Change in volume due to relaxation, expressed as the ratio V/V_0.
bool is_calculated(const Configuration &config)
Return true if all current properties have been been calculated for the configuration.
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
bool add_canon_config(const Configuration &config, Index &index)
Definition: Supercell.cc:590
bool add_config(const Configuration &config)
Definition: Supercell.cc:568
fs::path get_path() const
const SymOp * find_symop(const Configuration &motif, double tol)
Find first SymOp in the prim factor group such that apply(op, motif) can be used to fill the Supercel...
std::pair< DataFormatterDictInserter, RuntimeLibInserter > load_query_plugins(const ProjectSettings &set, DataFormatterDictInserter dict_it, RuntimeLibInserter lib_it)
Load enumerator plugins from a CASM project.
ProjectSettings & settings()
Definition: PrimClex.hh:116
bool get_else(T &t, const std::string &key, const T &default_value, Args...args) const
Definition: jsonParser.hh:749
Eigen::VectorXd VectorXd
const std::vector< size_type > & index() const
const Access orbit indices of ECI values
Definition: ECIContainer.hh:49
permute_const_iterator translate_begin() const
Begin iterator over pure translational permutations.
Definition: Supercell.cc:161
void clear_occupation()
Clear occupation.
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
Definition: algorithm.hh:10
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:52
Holds results of Configuration::insert.
UnitCellCoord uccoord(Index i) const
Definition: Supercell.hh:224
void set_id(Index _id)
const CompositionConverter & composition_axes() const
const Access CompositionConverter object
Definition: PrimClex.cc:237
void _generate_name() const
PermuteIterator find_translation() const
Returns a PermuteIterator corresponding to the first non-zero pure translation that maps the Configur...
UnitCell & unitcell()
std::vector< std::vector< Index > > get_index_converter(const Structure &struc, std::vector< Molecule > mol_list)
Helper Functions.
Definition: Structure.cc:1297
const ChemicalReference & chemical_reference() const
const Access ChemicalReference object
Definition: PrimClex.cc:251
bool is_less() const
Returns less than comparison.
std::string name() const
SCELV_A_B_C_D_E_F/i.
const Configuration & configuration(const std::string &configname) const
access configuration by name (of the form "scellname/[NUMBER]", e.g., ("SCEL1_1_1_1_0_0_0/0") ...
Definition: PrimClex.cc:347
Index find(const UnitCellCoord &bijk) const
Definition: Supercell.cc:39
double relaxed_magmom_per_species(const Configuration &_config)
Returns the relaxed magnetic moment, normalized per species.
jsonParser & write(jsonParser &json) const
Index size() const
Returns number of sites, NOT the number of primitives that fit in here.
ReturnArray< Array< double > > get_sublattice_composition() const
fs::path calc_status(std::string configname, std::string calctype) const
Return calculation status file path.
void set_deformation(const Eigen::Matrix3d &_deformation)
set_deformation sets ConfigDoF::has_deformation() to true
Definition: ConfigDoF.cc:119
jsonParser & write_param_composition(jsonParser &json) const
T const * end() const
Definition: Array.hh:197
Eigen::VectorXd relaxed_mag_basis(const Configuration &_config)
Returns the relaxed magnetic moment of each basis site.
Configuration(Supercell &_supercell, const jsonParser &source=jsonParser(), const ConfigDoF &_dof=ConfigDoF())
Construct a default Configuration.
fs::path POS(std::string configname) const
Return path to POS file.
ConfigIO::GenericConfigFormatter< std::string > configname()
Constructs DataFormmaterDictionary containing all Configuration DatumFormatters.
Definition: ConfigIO.cc:340
FillSupercell(Supercell &_scel, const SymOp &_op)
Constructor.
Eigen::VectorXd Correlation
Definition: Correlation.hh:9
Index get_id() const
Definition: Supercell.hh:303
void set_calc_properties(const jsonParser &json)
Read calculation results into the configuration.
jsonParser & write_properties(jsonParser &json) const
std::vector< PermuteIterator > factor_group() const
Returns the subgroup of the Supercell factor group that leaves the Configuration unchanged.
Class for comparison of Configurations (with the same Supercell)
Eigen::VectorXd site_frac(const Configuration &config)
Returns the composition as site fraction, in the order of Structure::get_struc_molecule.
void write_pos() const
Write the POS file to get_pos_path.
double formation_energy_per_species(const Configuration &config)
Returns the formation energy, normalized per species.
double lattice_deformation(const Configuration &_config)
Cost function that describes the degree to which lattice has relaxed.
Index vacancy_index() const
returns the index of vacancies in composition vectors
Definition: PrimClex.cc:290
Eigen::Matrix3d Matrix3d
ReturnArray< double > get_true_composition() const
PermuteIterator to_canonical() const
Returns the operation that applied to *this returns the canonical form.
permute_const_iterator translate_end() const
End iterator over pure translational permutations.
Definition: Supercell.cc:168
jsonParser & put_obj()
Puts new empty JSON object.
Definition: jsonParser.hh:276
Configuration in_canonical_supercell() const
Returns the canonical form Configuration in the canonical Supercell.
Print POSCAR with formating options.
Definition: VaspIO.hh:232
virtual void push_back(const SymOp &new_op)
Definition: SymGroup.cc:441
double crystallography_tol() const
Get current project crystallography tolerance.
const Supercell & get_supercell(Index i) const
const Access supercell by index
Definition: PrimClex.cc:311
void set_source(const jsonParser &source)
const displacement_matrix_t & displacement() const
Occupant displacements.
jsonParser & push_back(const T &value)
Puts new valued element at end of array of any type T for which 'jsonParser& to_json( const T &value...
Definition: jsonParser.hh:696
void clear_displacement()
Definition: ConfigDoF.cc:62
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
Definition: jsonParser.cc:500
void clear_occupation()
Definition: ConfigDoF.cc:58
bool has_volume_relaxation(const Configuration &_config)
SymGroup point_group() const
Returns the point group that leaves the Configuration unchanged.
void print_config_list(std::ostream &stream, int composition_flag) const
void set_occ(Index site_l, int val)
Set occupant variable on site l.
double relaxed_energy(const Configuration &config)
Returns the relaxed energy, normalized per unit cell.
const Eigen::Matrix3d & deformation() const
Applied strain.
double basis_deformation(const Configuration &_config)
Cost function that describes the degree to which basis sites have relaxed.
void clear()
Clear all DoF.
const vector_type & tau() const
Const access of the cartesian translation vector, 'tau'.
Definition: SymOp.hh:63
void set_lattice(const Lattice &new_lat)
Definition: SymGroup.cc:435
std::pair< bool, Eigen::MatrixXi > is_supercell(const Lattice &scel, const Lattice &unit, double tol)
Check if scel is a supercell of unitcell unit and some integer transformation matrix T...
Definition: Lattice.cc:1196
ConfigDoF::displacement_matrix_t displacement_matrix_t
double reference_energy(const Configuration &config)
Returns the reference energy, normalized per unit cell.
Log & err_log
Definition: settings.cc:106
bool is_primitive() const
Check if this is a primitive Configuration.
Log & default_err_log()
Definition: Log.hh:206
void error(const std::string &what)
Definition: Log.hh:86
bool has_relaxed_magmom(const Configuration &_config)
void set_selected(bool _selected)
double reference_energy_per_species(const Configuration &config)
Returns the reference energy, normalized per species.
UnitCellCoord uccoord(Index i) const
Definition: PrimGrid.cc:235
Eigen::MatrixXd displacement_matrix_t
Definition: ConfigDoF.hh:32
T const * begin() const
Definition: Array.hh:185
Configuration sub_configuration(Supercell &sub_scel, const Configuration &super_config, const UnitCell &origin=UnitCell(0, 0, 0))
Returns the sub-configuration that fills a particular Supercell.
const Eigen::MatrixXcd & phase_factor() const
Definition: Supercell.hh:233
Supercell & get_supercell() const
Get the Supercell for this Configuration.
displacement_t disp(Index i)
Definition: ConfigDoF.hh:73
Definition: Log.hh:9
bool is_array() const
Check if array type.
Definition: jsonParser.cc:281
const Eigen::Matrix3i & get_transf_mat() const
Definition: Supercell.hh:263
Index get_b(Index i) const
Definition: Supercell.hh:259
ReturnArray< double > get_composition() const
void clear_deformation()
Definition: ConfigDoF.cc:66
ConfigIO::GenericConfigFormatter< std::string > scelname()
Definition: ConfigIO.cc:348
std::string name
Definition: Molecule.hh:112
Lattice replace_vector(const Lattice &lat, const Eigen::Vector3d &new_vector, double tol)
jsonParser & write_dof(jsonParser &json) const
Functions used to perform write to config_list.json:
void read(const jsonParser &json)
Private members:
void init_displacement()
Set all occupant displacements to (0.,0.,0.)
ConfigIO::GenericConfigFormatter< Index > multiplicity()
Definition: ConfigIO.cc:381
double n_vacancy(const Configuration &config)
Returns the vacancy composition, as number per unit cell.
bool has_displacement() const
True if Configuration has displacement DoF.
permute_const_iterator permute_end() const
Definition: Supercell.cc:185
PermuteIterator from_canonical() const
Returns the operation that applied to the the canonical form returns *this.
const ClexDescription & default_clex() const
jsonParser & put_array()
Puts new empty JSON array.
Definition: jsonParser.hh:285
bool is_primitive(const Configuration &_config)
returns true if _config describes primitive cell of the configuration it describes ...
Object & apply(const Transform &f, Object &obj, Args &&...args)
bool operator<(const Configuration &B) const
Compare Configuration, via ConfigCompare.
std::string failure_type() const
Eigen::VectorXd species_frac(const Configuration &config)
Returns the composition as species fraction, with [Va] = 0.0, in the order of Structure::get_struc_mo...
jsonParser & write_source(jsonParser &json) const
permute_const_iterator permute_it(Index fg_index, Index trans_index) const
Definition: Supercell.cc:191
void set_occupation(const Array< int > &_occupation)
Definition: ConfigDoF.cc:84
A Configuration represents the values of all degrees of freedom in a Supercell.
const Structure & get_prim() const
const Access to primitive Structure
Definition: PrimClex.cc:260
Index num_sites() const
Definition: Supercell.hh:220
bool has_reference_energy(const Configuration &_config)
const ECIContainer & eci(const ClexDescription &key) const
Definition: PrimClex.cc:1076
Log & err_log() const
Definition: Log.hh:263
void init_deformation()
Set applied strain to Eigen::Matrix3d::Zero()
double crystallography_tol() const
Get the PrimClex crystallography_tol.
A sparse container of ECI values and their corresponding orbit indices.
Definition: ECIContainer.hh:12