CASM  1.1.0
A Clusters Approach to Statistical Mechanics
Configuration.cc
Go to the documentation of this file.
1 #include <boost/filesystem.hpp>
2 #include <boost/filesystem/fstream.hpp>
3 #include <boost/lexical_cast.hpp>
4 #include <boost/tokenizer.hpp>
5 #include <memory>
6 #include <sstream>
7 
10 #include "casm/basis_set/DoF.hh"
14 #include "casm/clex/Clexulator.hh"
39 
40 namespace CASM {
41 
42 template class HasPrimClex<Comparisons<Calculable<CRTPBase<Configuration> > > >;
43 template class HasSupercell<
44  Comparisons<Calculable<CRTPBase<Configuration> > > >;
45 template class ConfigCanonicalForm<
46  HasSupercell<Comparisons<Calculable<CRTPBase<Configuration> > > > >;
47 
48 namespace DB {
49 template class Indexed<CRTPBase<Configuration> >;
50 template class Named<CRTPBase<Configuration> >;
51 } // namespace DB
52 
54  std::shared_ptr<Supercell const> const &_supercell_ptr)
55  : m_supercell(_supercell_ptr.get()),
56  m_supercell_ptr(_supercell_ptr),
57  m_configdof(make_configdof(*_supercell_ptr)) {}
58 
60  std::shared_ptr<Supercell const> const &_supercell_ptr,
61  ConfigDoF const &_dof)
62  : m_supercell(_supercell_ptr.get()),
63  m_supercell_ptr(_supercell_ptr),
64  m_configdof(_dof) {}
65 
67  const std::shared_ptr<Supercell const> &_supercell_ptr) {
68  return Configuration{_supercell_ptr};
69 }
70 
72  const std::shared_ptr<Supercell const> &_supercell_ptr, double _tol) {
73  return Configuration{_supercell_ptr, make_configdof(*_supercell_ptr, _tol)};
74 }
75 
76 // *** The following constructors should be avoided in new code, if possible
77 
80  : m_supercell(&_supercell),
81  m_configdof(Configuration::zeros(_supercell).configdof()) {}
82 
85  const ConfigDoF &_configdof)
86  : m_supercell(&_supercell), m_configdof(_configdof) {}
87 
89  return Configuration(_scel, make_configdof(_scel));
90 }
91 
92 Configuration Configuration::zeros(Supercell const &_scel, double _tol) {
93  return Configuration(_scel, make_configdof(_scel, _tol));
94 }
95 
96 // void Configuration::clear() {
97 // _modify_dof();
98 // m_configdof.clear();
99 // }
100 
102  _modify_dof();
103  set_occupation(Eigen::VectorXi::Zero(this->size()));
104 }
105 
106 void Configuration::set_occ(Index site_l, int val) {
107  _modify_dof();
108  m_configdof.occ(site_l) = val;
109 }
110 
113  if (!cache().contains("is_primitive")) {
114  bool result =
116  cache_insert("is_primitive", result);
117  return result;
118  }
119  return cache()["is_primitive"].get<bool>();
120 }
121 
127  ConfigIsEquivalent f(*this, crystallography_tol());
128  const Supercell &scel = supercell();
129  auto begin = scel.sym_info().translate_begin();
130  auto end = scel.sym_info().translate_end();
131  if (++begin == end) {
132  return end;
133  }
134  return std::find_if(begin, end, f);
135 }
136 
142  Configuration tconfig{*this};
143 
144  // check if config is primitive, and if not, obtain a translation that maps
145  // the config on itself
146  while (true) {
147  PermuteIterator result = tconfig.find_translation();
148 
149  if (result == tconfig.supercell().sym_info().translate_end()) {
150  break;
151  }
152 
153  // replace one of the lattice vectors with the translation
154  Lattice new_lat =
155  replace_vector(tconfig.ideal_lattice(), result.sym_op().tau(),
156  crystallography_tol())
158  .reduced_cell();
159 
160  // create a sub configuration in the new supercell
161  if (supercell().has_primclex()) {
162  tconfig = sub_configuration(
163  std::make_shared<Supercell>(&primclex(), new_lat), tconfig);
164  } else {
165  tconfig = sub_configuration(
166  std::make_shared<Supercell>(supercell().shared_prim(), new_lat),
167  tconfig);
168  }
169  }
170 
171  return tconfig;
172 }
173 
180  Configuration result =
181  DB::in_canonical_supercell(*this, primclex().db<Supercell>());
182  result.supercell().set_primclex(&primclex());
183  return result;
184 }
185 
197 ConfigInsertResult Configuration::insert(bool primitive_only) const {
198  auto result = DB::make_canonical_and_insert(*this, primclex().db<Supercell>(),
199  primclex().db<Configuration>(),
200  primitive_only);
201  if (result.insert_primitive) {
202  result.primitive_it->supercell().set_primclex(&primclex());
203  }
204  if (result.insert_canonical) {
205  result.canonical_it->supercell().set_primclex(&primclex());
206  }
207  return result;
208 }
209 
212 std::vector<PermuteIterator> Configuration::factor_group() const {
213  return invariant_subgroup();
214 }
215 
218 std::vector<PermuteIterator> Configuration::invariant_subgroup() const {
219  std::vector<PermuteIterator> fg = ConfigurationBase::invariant_subgroup();
220  if (fg.size() == 0) {
221  err_log() << "Something went very wrong in invariant_subgroup returning "
222  "group size 0"
223  << std::endl;
224  }
225  int mult = this->prim().factor_group().size() / fg.size();
226  cache_insert("multiplicity", mult);
227  return fg;
228 }
229 
231  if (!cache().contains("is_canonical")) {
232  bool result = ConfigurationBase::is_canonical();
233  cache_insert("is_canonical", result);
234  return result;
235  }
236  return cache()["is_canonical"].get<bool>();
237 }
238 
240 std::vector<PermuteIterator> Configuration::point_group() const {
241  std::vector<PermuteIterator> config_factor_group = factor_group();
242  std::vector<PermuteIterator> result;
243  for (int i = 0; i < config_factor_group.size(); i++) {
244  if (i == 0 || config_factor_group[i].factor_group_index() !=
245  config_factor_group[i - 1].factor_group_index())
246  result.push_back(config_factor_group[i]);
247  }
248 
249  return result;
250 }
251 
253 std::string Configuration::point_group_name() const {
254  if (!cache().contains("point_group_name")) {
255  cache_insert(
256  "point_group_name",
257  make_sym_group(this->point_group(),
258  this->supercell().sym_info().supercell_lattice())
259  .get_name());
260  }
261  return cache()["point_group_name"].get<std::string>();
262 }
263 
264 //********** ACCESSORS ***********
265 
267  return supercell().lattice();
268 }
269 
272  : config(_config),
273  // Find primitive canonical config:
274  prim_canon_config(config.primitive().in_canonical_supercell()) {
275  // Find the transformation of prim_canon_config and gives config:
276  //
277  // op1: a prim_canon_config.supercell() PermuteIterator
278  // op2: a prim().point_group() SymOp
279  // FillSupercell fill_supercell_f {supercell()};
280  // *this == fill_supercell_f(op2, copy_apply(op1, prim_canon_config));
281 
282  // first find op2 == *res.first
285  config.prim().point_group().begin(), config.prim().point_group().end(),
286  config.crystallography_tol());
287  this->from_canonical_lat = *res.first;
288  this->transf_mat = iround(res.second);
289 
290  // given op2, find op1
291  auto is_equal_to_f = config.equal_to();
294  FillSupercell fill_supercell_f{config.supercell()};
295  for (auto op1 = begin; op1 != end; ++op1) {
296  auto test = copy_apply(op1, this->prim_canon_config);
297  Configuration super_configuration = fill_supercell_f(*res.first, test);
298  if (is_equal_to_f(super_configuration)) {
299  this->from_canonical_config = op1;
300  return;
301  }
302  }
303 
304  throw std::runtime_error(
305  "Error in RefToCanonicalPrim: could not find solution");
306 }
307 
308 std::string RefToCanonicalPrim::name() const {
309  return config.supercell().name() + "/super." +
311  prim_canon_config.name() + ".equiv." +
314 }
315 
340  if (id() != "none") {
341  return supercell().name() + "/" + id();
342  }
343 
344  if (!supercell().has_primclex()) {
345  throw std::runtime_error(
346  "Error in Configuration::generate_name_impl: No PrimClex pointer.");
347  }
348 
349  const auto &db = primclex().db<Configuration>();
350  const Lattice &canon_scel_lat = supercell().canonical_form().lattice();
351  bool is_canon_equiv_lat =
352  xtal::is_equivalent(this->supercell().lattice(), canon_scel_lat);
353 
354  // If in the canonical equivalent supercell lattice:
355  if (is_canon_equiv_lat) {
356  // put Configuration in canonical supercell
357  Configuration canon_scel_config =
359 
360  // if canonical
361  if (canon_scel_config.is_canonical()) {
362  auto find_it = db.search(canon_scel_config);
363 
364  // if already in database
365  if (find_it != db.end()) {
366  // set id
367  set_id(find_it->id());
368  return supercell().name() + "/" + id();
369  }
370  // if not in database
371  else {
372  return supercell().name() + "/none";
373  }
374  }
375  // if non-canonical
376  else {
377  // get canonical form and 'from_canonical' op
378  Configuration canon_config = canon_scel_config.canonical_form();
379  auto op = canon_scel_config.from_canonical();
380 
381  // get canonical form id if already in database, else 'none'
382  auto find_it = db.search(canon_config);
383  std::string canon_config_id = "none";
384  if (find_it != db.end()) {
385  canon_config_id = find_it->id();
386  }
387 
388  // construct name
389  return supercell().name() + "/" + canon_config_id + ".equiv." +
390  std::to_string(op.factor_group_index()) + "." +
391  std::to_string(op.translation_index());
392  }
393  }
394 
395  RefToCanonicalPrim ref(*this);
396  return ref.name();
397 }
398 
401 
402 const Supercell &Configuration::supercell() const { return *m_supercell; }
403 
405  return supercell().uccoord(site_l);
406 }
407 
409  return supercell().linear_index(bijk);
410 }
411 
412 int Configuration::sublat(Index site_l) const {
413  return supercell().sublat(site_l);
414 }
415 
416 const Molecule &Configuration::mol(Index site_l) const {
417  return prim().basis()[sublat(site_l)].occupant_dof()[occ(site_l)];
418 }
419 
424  if (!cache().contains("multiplicity")) {
425  int result =
426  this->prim().factor_group().size() / this->factor_group().size();
427  cache_insert("multiplicity", result);
428  return result;
429  }
430  return cache()["multiplicity"].get<int>();
431 }
432 
434  auto all_props = calc_properties_map();
435  configdof().apply_sym(op);
436  for (auto it = all_props.begin(); it != all_props.end(); ++it) {
437  std::string calctype = it->first;
438  set_calc_properties(copy_apply(op, it->second), calctype);
439  }
440  return *this;
441 }
442 
447 std::vector<Eigen::VectorXd> Configuration::sublattice_composition() const {
448  // get the number of each molecule
449  auto _sublat_num_each_molecule = sublat_num_each_molecule();
450  std::vector<Eigen::VectorXd> sublattice_composition(
451  _sublat_num_each_molecule.size());
452 
453  // divide by number of sites per sublattice ( supercell volume )
454  for (Index i = 0; i < _sublat_num_each_molecule.size(); i++) {
456  Eigen::VectorXd::Zero(_sublat_num_each_molecule[i].size());
457  for (Index j = 0; j < _sublat_num_each_molecule[i].size(); j++) {
458  sublattice_composition[i][j] =
459  (1.0 * _sublat_num_each_molecule[i][j]) / supercell().volume();
460  }
461  }
462 
463  return sublattice_composition;
464 }
465 
470 std::vector<Eigen::VectorXi> Configuration::sublat_num_each_molecule() const {
471  Index i;
472 
473  // create an array to count the number of each molecule
474  std::vector<Eigen::VectorXi> sublat_num_each_molecule;
475  for (i = 0; i < prim().basis().size(); i++) {
476  sublat_num_each_molecule.push_back(
477  Eigen::VectorXi::Zero(prim().basis()[i].occupant_dof().size()));
478  }
479 
480  // count the number of each molecule by sublattice
481  for (i = 0; i < size(); i++) {
483  }
484 
486 }
487 
492  // get the number of each molecule type
493  Eigen::VectorXi _num_each_molecule = num_each_molecule();
494 
496  int num_atoms = 0;
497 
498  // need to know which molecules are vacancies
499  auto struc_mol = xtal::struc_molecule_name(prim());
500 
501  Index i;
502  for (i = 0; i < struc_mol.size(); i++) {
503  if (xtal::is_vacancy(struc_mol[i])) {
504  // set to zero, so the Va concentration is reported as 0.0
505  _num_each_molecule[i] = 0;
506  }
507  num_atoms += _num_each_molecule[i];
508  }
509 
510  // calculate the comp (not including vacancies) from the number of each
511  // molecule
512  return _num_each_molecule.cast<double>() / double(num_atoms);
513 }
514 
519  return num_each_molecule().cast<double>() / size();
520 }
521 
524 Eigen::VectorXi Configuration::num_each_molecule() const {
526 }
527 
530  if (!primclex().has_composition_axes()) {
531  std::cerr << "Error in Configuration::param_composition()" << std::endl;
532  std::cerr << " Composition axes are not set." << std::endl;
533  exit(1);
534  }
535 
536  return primclex().composition_axes().param_composition(num_each_component());
537 }
538 
542  // component order used for param_composition
543  std::vector<std::string> components =
544  primclex().composition_axes().components();
545 
546  // initialize
547  Eigen::VectorXd num_each_component = Eigen::VectorXd::Zero(components.size());
548 
549  // [basis_site][site_occupant_index]
550  auto convert = make_index_converter(prim(), components);
551 
552  // count the number of each component
553  for (Index i = 0; i < size(); i++) {
554  num_each_component[convert[sublat(i)][occ(i)]] += 1.0;
555  }
556 
557  // normalize per prim cell
558  for (Index i = 0; i < components.size(); i++) {
560  }
561 
562  return num_each_component;
563 }
564 
566  return less()(B);
567 }
568 
570 
572  return ConfigIsEquivalent(*this);
573 }
574 
575 std::pair<std::string, std::string> Configuration::split_name(
576  std::string configname) {
577  std::vector<std::string> splt_vec;
578  boost::split(splt_vec, configname, boost::is_any_of("/"),
579  boost::token_compress_on);
580  if (splt_vec.size() != 2) {
581  err_log().error("Parsing configuration name");
582  err_log() << "configuration '" << configname << "' not valid." << std::endl;
583  err_log() << "must have form: scelname/configid" << std::endl;
584  throw std::invalid_argument(
585  "Error in Configuration::split_name(const std::string &configname) "
586  "const: Not valid");
587  }
588 
589  return std::make_pair(splt_vec[0], splt_vec[1]);
590 }
591 
592 bool Configuration::eq_impl(const Configuration &B) const {
593  if (supercell() != B.supercell()) {
594  return false;
595  }
596  ConfigIsEquivalent f(*this, crystallography_tol());
597  return f(B);
598 }
599 
600 Configuration sub_configuration(std::shared_ptr<Supercell const> sub_scel_ptr,
601  const Configuration &super_config,
602  const UnitCell &origin) {
603  if (sub_scel_ptr->shared_prim() != super_config.shared_prim()) {
604  throw std::runtime_error("Error sub_configuration: prim is not the same.");
605  }
606 
607  Configuration sub_config{sub_scel_ptr};
608  // copy global dof
609  for (auto const &dof : super_config.configdof().global_dofs()) {
610  sub_config.configdof().set_global_dof(dof.first, dof.second.values());
611  }
612 
613  // copy site dof
614  for (Index i = 0; i < sub_config.size(); i++) {
615  // unitcell of site i in sub_config
616  UnitCellCoord unitcellcoord = sub_config.uccoord(i);
617 
618  // equivalent site in superconfig
619  Index site_index =
620  super_config.supercell().linear_index(unitcellcoord + origin);
621 
622  // copy dof from superconfig to this:
623 
624  // occupation
625  if (super_config.has_occupation()) {
626  sub_config.configdof().occ(i) = super_config.occ(site_index);
627  }
628  }
629 
630  for (auto const &dof : super_config.configdof().local_dofs()) {
632  sub_config.configdof().local_dof(dof.first));
633  for (Index i = 0; i < sub_config.size(); i++) {
634  // unitcell of site i in sub_config
635  UnitCellCoord unitcellcoord = sub_config.uccoord(i);
636 
637  // equivalent site in superconfig
638  Index scel_site_index =
639  super_config.supercell().linear_index(unitcellcoord + origin);
640 
641  // copy dof from superconfig to this:
642  res_ref.site_value(i) = dof.second.site_value(scel_site_index);
643  }
644  }
645 
646  return sub_config;
647 }
648 
649 namespace {
650 
655 Configuration make_non_canon_configuration(const PrimClex &primclex,
656  std::string name) {
657  std::string format = "$CANON_CONFIGNAME.equiv.$FG_PERM.$TRANS_PERM";
658 
659  // split $CANON_CONFIGNAME & $FG_PERM & $TRANS_PERM
660  std::vector<std::string> tokens;
661  boost::split(tokens, name, boost::is_any_of("."), boost::token_compress_on);
662  std::string canon_config_name = tokens[0];
663  if (tokens.size() != 4) {
664  err_log().error("In make_configuration");
665  err_log() << "expected format: " << format << "\n";
666  err_log() << "name: " << name << std::endl;
667  err_log() << "tokens: " << tokens << std::endl;
668  throw std::invalid_argument(
669  "Error in make_configuration: configuration name format error");
670  }
671 
672  Configuration canon_config =
673  *primclex.db<Configuration>().find(canon_config_name);
674  Index fg_index = boost::lexical_cast<Index>(tokens[2]);
675  Index trans_index = boost::lexical_cast<Index>(tokens[3]);
676 
677  return CASM::apply(
678  canon_config.supercell().sym_info().permute_it(fg_index, trans_index),
679  canon_config);
680 }
681 
694 Configuration make_super_configuration(const PrimClex &primclex,
695  std::string name) {
696  // expected format
697  std::string format = "$SCEL_NAME/super.$PRIM_FG_OP2.$NONCANON_CONFIG_NAME";
698 
699  // tokenize name
700  std::vector<std::string> tokens;
701  boost::split(tokens, name, boost::is_any_of("./"), boost::token_compress_on);
702 
703  std::string scelname, non_canon_config_name;
704  Index fg_op_index = 0;
705 
706  if (tokens[1] != "super" && tokens[2] != "super") {
707  err_log().error("In make_configuration");
708  err_log() << "expected format: " << format << "\n";
709  err_log() << "name: " << name << std::endl;
710  err_log() << "tokens: " << tokens << std::endl;
711 
712  throw std::invalid_argument(
713  "Error in make_configuration: configuration name format error");
714  }
715 
716  try {
717  // parse, if canonical equivalent lattice
718  if (tokens[1] == "super") {
719  scelname = tokens[0];
720  fg_op_index = boost::lexical_cast<Index>(tokens[2]);
721  non_canon_config_name = tokens[3] + '/' + tokens[4] + '.' + tokens[5] +
722  '.' + tokens[6] + '.' + tokens[7];
723  }
724  // parse, if not canonical equivalent lattice
725  else { // if(tokens[2] == "super")
726  scelname = tokens[0] + '.' + tokens[1];
727  fg_op_index = boost::lexical_cast<Index>(tokens[3]);
728  non_canon_config_name = tokens[4] + '/' + tokens[5] + '.' + tokens[6] +
729  '.' + tokens[7] + '.' + tokens[8];
730  }
731  } catch (...) {
732  err_log().error("In make_configuration");
733  err_log() << "expected format: " << format << "\n";
734  err_log() << "name: " << name << std::endl;
735  err_log() << "tokens: " << tokens << std::endl;
736 
737  throw std::invalid_argument(
738  "Error in make_configuration: configuration name format error");
739  }
740 
741  // -- Generate primitive equivalent configuration
742 
743  // prim equiv name
744  Configuration non_canon_config =
745  make_non_canon_configuration(primclex, non_canon_config_name);
746 
747  const auto &sym_op = primclex.prim().factor_group()[fg_op_index];
748 
749  // canonical equivalent supercells can be found in the database
750  if (tokens[1] == "super") {
751  return fill_supercell(sym_op, non_canon_config,
752  *primclex.db<Supercell>().find(scelname));
753  }
754  // non canonical equivalent supercells must be constructed
755  else {
756  return fill_supercell(sym_op, non_canon_config,
758  }
759 }
760 
761 } // namespace
762 
784  // if most general case:
785  // format = $SCEL_NAME/super.$PRIM_FG_OP2.$NONCANON_CONFIG_NAME
786  if (name.find("super") != std::string::npos) {
787  return make_super_configuration(primclex, name);
788  }
789 
790  // if non-canonical configuration in canonical equivalent supercell:
791  // format = $CANON_CONFIG_NAME.equiv.$FG_PERM.$TRANS_PERM
792  if (name.find("equiv") != std::string::npos) {
793  return make_non_canon_configuration(primclex, name);
794  }
795 
796  // if $CANON_SCELNAME/$CANON_INDEX
797  return *primclex.db<Configuration>().find(name);
798 }
799 
802  Clexulator const &clexulator) {
803  return correlations(config.configdof(), config.supercell(), clexulator);
804 }
805 
808  const Configuration &config,
809  Clexulator const &clexulator) {
810  return corr_contribution(linear_unitcell_index, config.configdof(),
811  config.supercell(), clexulator);
812 }
813 
816 Eigen::VectorXd point_corr(Index linear_unitcell_index, Index neighbor_index,
817  const Configuration &config,
818  Clexulator const &clexulator) {
819  return point_corr(linear_unitcell_index, neighbor_index, config.configdof(),
820  config.supercell(), clexulator);
821 }
822 
826  Clexulator const &clexulator, DoFKey &key) {
827  return gradcorrelations(config.configdof(), config.supercell(), clexulator,
828  key);
829 }
830 
833  return config.param_composition();
834 }
835 
838  return config.num_each_component();
839 }
840 
843  if (config.primclex().vacancy_allowed()) {
844  return comp_n(config)[config.primclex().vacancy_index()];
845  }
846  return 0.0;
847 }
848 
853  return comp_n(config).sum() - n_vacancy(config);
854 }
855 
862  if (config.primclex().vacancy_allowed()) {
863  v(config.primclex().vacancy_index()) = 0.0;
864  }
865  return v / v.sum();
866 }
867 
871  return comp_n(config) / config.prim().basis().size();
872 }
873 
875 double energy(const Configuration &config) {
876  return config.calc_properties().scalar("energy") /
877  config.supercell().volume();
878 }
879 
882  return energy(config) / n_species(config);
883 }
884 
888 }
889 
894  return config.primclex().chemical_reference()(config);
895 }
896 
900 }
901 
907 }
908 
911  const auto &primclex = config.primclex();
912  auto formation_energy = primclex.settings().clex("formation_energy");
913  Clexulator clexulator = primclex.clexulator(formation_energy.bset);
915 
916  if (eci.index().back() >= clexulator.corr_size()) {
918  err_log.error<Log::standard>("bset and eci mismatch");
919  err_log << "using cluster expansion: 'formation_energy'" << std::endl;
920  err_log << "basis set size: " << clexulator.corr_size() << std::endl;
921  err_log << "max eci index: " << eci.index().back() << std::endl;
922  throw std::runtime_error("Error: bset and eci mismatch");
923  }
924 
925  return eci * correlations(config, clexulator);
926 }
927 
931 }
932 
935 double atomic_deformation(const Configuration &_config) {
936  return _config.calc_properties().scalar("atomic_deformation");
937 }
938 
940 double lattice_deformation(const Configuration &_config) {
941  return _config.calc_properties().scalar("lattice_deformation");
942 }
943 
945 double volume_relaxation(const Configuration &_config) {
946  StrainConverter tconvert("BIOT");
947  return tconvert.rollup_E(_config.calc_properties().global.at("Ustrain"))
948  .determinant();
949 }
950 
952 double relaxed_magmom(const Configuration &_config) {
953  return _config.calc_properties().scalar("relaxed_magmom");
954 }
955 
958  return relaxed_magmom(_config) / n_species(_config);
959 }
960 
964  return _config.calc_properties().site.at("relaxed_forces");
965 }
966 
969 double rms_force(const Configuration &_config) {
970  // Get RMS force:
971  Eigen::MatrixXd F = relaxed_forces(_config);
972 
973  return sqrt((F * F.transpose()).trace() / double(F.cols()));
974 }
975 
979  const Configuration &_config2) {
980  if (_config1.supercell() != _config2.supercell()) {
981  throw std::runtime_error(
982  "Misuse of basic config_diff: configs are not in same supercell");
983  }
984  std::vector<UnitCellCoord> uccoords;
985  for (Index i = 0; i < _config1.occupation().size(); i++) {
986  if (_config1.occ(i) != _config2.occ(i)) {
987  uccoords.push_back(_config1.uccoord(i));
988  }
989  }
990  IntegralCluster perturb(_config1.prim(), uccoords.begin(), uccoords.end());
991  return perturb;
992 }
993 
997  const Configuration &_config2) {
998  std::vector<PermuteIterator> non_fg_its;
999  std::set_difference(_config2.supercell().sym_info().permute_begin(),
1000  _config2.supercell().sym_info().permute_end(),
1001  _config2.factor_group().begin(),
1002  _config2.factor_group().end(),
1003  std::back_inserter(non_fg_its));
1004  int min_size = config_diff(_config1, _config2).size();
1005  if (non_fg_its.size() == 0) {
1006  return _config2;
1007  }
1008  PermuteIterator best_it = *(non_fg_its.begin());
1009  for (auto it = non_fg_its.begin(); it != non_fg_its.end(); ++it) {
1010  int size = config_diff(_config1, copy_apply(*it, _config2)).size();
1011  if (size < min_size) {
1012  best_it = *it;
1013  min_size = size;
1014  }
1015  }
1016  if (min_size == config_diff(_config1, _config2).size()) {
1017  return _config2;
1018  }
1019  return copy_apply(best_it, _config2);
1020 }
1021 
1025  const Configuration &_bg, IntegralCluster &_clust) {
1026  if (_config.supercell() != _bg.supercell()) {
1027  throw std::runtime_error(
1028  "Misuse of basic config_clip: configs are not in same supercell");
1029  }
1030  Configuration tmp = _bg;
1031  std::vector<Index> l_inds;
1032  std::vector<Index> l_values;
1033  for (auto &site : _clust) {
1034  l_inds.push_back(_config.linear_index(site));
1035  l_values.push_back(_config.occ(_config.linear_index(site)));
1036  }
1037  for (Index i = 0; i < l_inds.size(); i++) {
1038  tmp.set_occ(l_inds[i], l_values[i]);
1039  }
1040  return tmp;
1041 }
1042 
1045 bool is_primitive(const Configuration &_config) {
1046  return _config.is_primitive();
1047 }
1048 
1051 bool is_canonical(const Configuration &_config) {
1052  return _config.is_canonical();
1053 }
1054 
1055 bool has_energy(const Configuration &_config) {
1056  return _config.calc_properties().has_scalar("energy");
1057 }
1058 
1059 bool has_reference_energy(const Configuration &_config) {
1060  return _config.primclex().has_composition_axes() &&
1061  _config.primclex().has_chemical_reference();
1062 }
1063 
1064 bool has_formation_energy(const Configuration &_config) {
1065  return has_energy(_config) && has_reference_energy(_config);
1066 }
1067 
1068 bool has_rms_force(const Configuration &_config) {
1069  MappedProperties const &props = _config.calc_properties();
1070  auto it = props.site.find("relaxed_forces");
1071  return it != props.site.end() && it->second.cols();
1072 }
1073 
1075  return _config.calc_properties().has_scalar("atomic_deformation");
1076 }
1077 
1079  return _config.calc_properties().has_scalar("lattice_deformation");
1080 }
1081 
1082 bool has_volume_relaxation(const Configuration &_config) {
1083  return _config.calc_properties().global.count("Ustrain");
1084 }
1085 
1086 bool has_relaxed_magmom(const Configuration &_config) {
1087  return _config.calc_properties().has_scalar("relaxed_magmom");
1088 }
1089 
1090 bool has_relaxed_mag_basis(const Configuration &_config) {
1091  return _config.calc_properties().site.count("relaxed_mag_basis");
1092 }
1093 
1094 std::ostream &operator<<(std::ostream &sout, const Configuration &c) {
1095  sout << c.name() << "\n";
1096  // if(c.has_deformation()) {
1097  // sout << "Deformation:\n" << c.deformation() << std::endl;
1098  //}
1099 
1100  for (Index i = 0; i < c.size(); ++i) {
1101  sout << "Linear index: " << i << " UnitCellCoord: " << c.uccoord(i)
1102  << std::endl;
1103  if (c.has_occupation()) {
1104  sout << " Occupation: " << c.occ(i) << " (" << c.mol(i).name() << ")\n";
1105  }
1106  // if(c.has_displacement()) {
1107  // sout << " Displacement: " << c.disp(i).transpose() << "\n";
1108  //}
1109  }
1110 
1111  return sout;
1112 }
1113 
1116 Eigen::VectorXd correlations(const ConfigDoF &configdof, const Supercell &scel,
1117  Clexulator const &clexulator) {
1118  // Size of the supercell will be used for normalizing correlations to a per
1119  // primitive cell value
1120  int scel_vol = scel.volume();
1121 
1122  Eigen::VectorXd correlations = Eigen::VectorXd::Zero(clexulator.corr_size());
1123 
1124  // Inform Clexulator of the bitstring
1125 
1126  // Holds contribution to global correlations from a particular neighborhood
1127  Eigen::VectorXd tcorr = correlations;
1128  // std::vector<double> corr(clexulator.corr_size(), 0.0);
1129 
1130  for (int v = 0; v < scel_vol; v++) {
1131  // Fill up contributions
1132  clexulator.calc_global_corr_contribution(
1133  configdof, scel.nlist().sites(v).data(), end_ptr(scel.nlist().sites(v)),
1134  tcorr.data(), end_ptr(tcorr));
1135 
1136  correlations += tcorr;
1137  }
1138 
1139  correlations /= (double)scel_vol;
1140 
1141  return correlations;
1142 }
1143 
1148  const ConfigDoF &configdof,
1149  const Supercell &scel,
1150  Clexulator const &clexulator) {
1151  if (linear_unitcell_index >= scel.volume()) {
1152  std::stringstream msg;
1153  msg << "Error in point_corr: linear_unitcell_index out of range ("
1154  << linear_unitcell_index << " >= " << scel.volume() << ")";
1155  throw std::runtime_error(msg.str());
1156  }
1157  Eigen::VectorXd correlations = Eigen::VectorXd::Zero(clexulator.corr_size());
1158 
1159  auto const &unitcell_nlist = scel.nlist().sites(linear_unitcell_index);
1160  clexulator.calc_global_corr_contribution(
1161  configdof, unitcell_nlist.data(), end_ptr(unitcell_nlist),
1162  correlations.data(), end_ptr(correlations));
1163 
1164  return correlations;
1165 }
1166 
1169 Eigen::VectorXd point_corr(Index linear_unitcell_index, Index neighbor_index,
1170  const ConfigDoF &configdof, const Supercell &scel,
1171  Clexulator const &clexulator) {
1172  if (linear_unitcell_index >= scel.volume()) {
1173  std::stringstream msg;
1174  msg << "Error in point_corr: linear_unitcell_index out of range ("
1175  << linear_unitcell_index << " >= " << scel.volume() << ")";
1176  throw std::runtime_error(msg.str());
1177  }
1178 
1179  Eigen::VectorXd correlations = Eigen::VectorXd::Zero(clexulator.corr_size());
1180 
1181  auto const &unitcell_nlist = scel.nlist().sites(linear_unitcell_index);
1182  if (neighbor_index >= clexulator.n_point_corr()) {
1183  std::stringstream msg;
1184  msg << "Error in point_corr: neighbor_index out of range ("
1185  << neighbor_index << " >= " << clexulator.n_point_corr() << ")";
1186  throw std::runtime_error(msg.str());
1187  }
1188  clexulator.calc_global_corr_contribution(
1189  configdof, unitcell_nlist.data(), end_ptr(unitcell_nlist),
1190  correlations.data(), end_ptr(correlations));
1191 
1192  return correlations;
1193 }
1194 
1198  const Supercell &scel,
1199  Clexulator const &clexulator, DoFKey &key) {
1200  ClexParamKey paramkey;
1201  ClexParamKey corr_key(clexulator.param_pack().key("corr"));
1202  ClexParamKey dof_key;
1203  if (key == "occ") {
1204  paramkey = clexulator.param_pack().key("diff/corr/" + key + "_site_func");
1205  dof_key = clexulator.param_pack().key("occ_site_func");
1206  } else {
1207  paramkey = clexulator.param_pack().key("diff/corr/" + key + "_var");
1208  dof_key = clexulator.param_pack().key(key + "_var");
1209  }
1210 
1211  std::string em_corr, em_dof;
1212  em_corr = clexulator.param_pack().eval_mode(corr_key);
1213  em_dof = clexulator.param_pack().eval_mode(dof_key);
1214 
1215  // this const_cast is not great...
1216  // but it seems like the only place passing const Clexulator is a problem and
1217  // it is not actually changing clexulator before/after this function
1218  const_cast<Clexulator &>(clexulator)
1219  .param_pack()
1220  .set_eval_mode(corr_key, "DIFF");
1221  const_cast<Clexulator &>(clexulator)
1222  .param_pack()
1223  .set_eval_mode(dof_key, "DIFF");
1224 
1225  Eigen::MatrixXd gcorr;
1226  Index scel_vol = scel.volume();
1227  if (DoF::BasicTraits(key).global()) {
1228  Eigen::MatrixXd gcorr_func = configdof.global_dof(key).values();
1229  gcorr.setZero(gcorr_func.size(), clexulator.corr_size());
1230  // Holds contribution to global correlations from a particular neighborhood
1231 
1232  // std::vector<double> corr(clexulator.corr_size(), 0.0);
1233  for (int v = 0; v < scel_vol; v++) {
1234  // Fill up contributions
1235  clexulator.calc_global_corr_contribution(configdof,
1236  scel.nlist().sites(v).data(),
1237  end_ptr(scel.nlist().sites(v)));
1238 
1239  for (Index c = 0; c < clexulator.corr_size(); ++c)
1240  gcorr.col(c) += clexulator.param_pack().read(paramkey(c));
1241  }
1242  } else {
1243  Eigen::MatrixXd gcorr_func;
1244  gcorr.setZero(configdof.local_dof(key).values().size(),
1245  clexulator.corr_size());
1246  // Holds contribution to global correlations from a particular neighborhood
1247  Index l;
1248  for (int v = 0; v < scel_vol; v++) {
1249  // Fill up contributions
1250  clexulator.calc_global_corr_contribution(configdof,
1251  scel.nlist().sites(v).data(),
1252  end_ptr(scel.nlist().sites(v)));
1253 
1254  for (Index c = 0; c < clexulator.corr_size(); ++c) {
1255  gcorr_func = clexulator.param_pack().read(paramkey(c));
1256 
1257  for (Index n = 0; n < scel.nlist().sites(v).size(); ++n) {
1258  l = scel.nlist().sites(v)[n];
1259  // for(Index i=0; i<gcorr_func.cols(); ++i){
1260  gcorr.block(l * gcorr_func.rows(), c, gcorr_func.rows(), 1) +=
1261  gcorr_func.col(n);
1262  // std::cout << "Block: (" << l * gcorr_func.rows() << ", " << c << ",
1263  // " << gcorr_func.rows() << ", " << 1 << ") += " <<
1264  // gcorr_func.col(n).transpose() << "\n";
1265  //}
1266  }
1267  }
1268  }
1269  }
1270  const_cast<Clexulator &>(clexulator)
1271  .param_pack()
1272  .set_eval_mode(corr_key, em_corr);
1273  const_cast<Clexulator &>(clexulator)
1274  .param_pack()
1275  .set_eval_mode(dof_key, em_dof);
1276 
1277  return gcorr;
1278 }
1279 
1282 Eigen::VectorXi num_each_molecule(const ConfigDoF &configdof,
1283  const Supercell &scel) {
1284  auto mol_names = xtal::struc_molecule_name(scel.prim());
1285  // [basis_site][site_occupant_index]
1286  auto convert = make_index_converter(scel.prim(), mol_names);
1287 
1288  // create an array to count the number of each molecule
1289  Eigen::VectorXi num_each_molecule = Eigen::VectorXi::Zero(mol_names.size());
1290 
1291  // count the number of each molecule
1292  for (Index i = 0; i < configdof.size(); i++) {
1293  num_each_molecule(convert[scel.sublat(i)][configdof.occ(i)])++;
1294  }
1295 
1296  return num_each_molecule;
1297 }
1298 
1301 Eigen::VectorXd comp_n(const ConfigDoF &configdof, const Supercell &scel) {
1302  return num_each_molecule(configdof, scel).cast<double>() / scel.volume();
1303 }
1304 
1305 } // namespace CASM
std::shared_ptr< Structure const > shared_prim
Specifies traits of (possibly) anisotropic crystal properties.
bool global() const
Returns true if type is global.
Key for indexing clexulator parameters Contains pointer to implementation of the Key.
virtual std::string eval_mode(ClexParamKey const &_key) const =0
Check evaluation mode for ClexParamPack parameter Choices are at least.
ClexParamKey const & key(std::string const &_name) const
Obtain key for managed data block by name.
virtual Eigen::MatrixXd const & read(ClexParamKey const &_key) const =0
Returns const reference to parameter array for parameter specified by.
Evaluates correlations.
Definition: Clexulator.hh:440
size_type corr_size() const
Number of correlations.
Definition: Clexulator.hh:480
ClexParamPack const & param_pack() const
Obtain const reference to abstract ClexParamPack object.
Definition: Clexulator.hh:489
void calc_global_corr_contribution(ConfigDoF const &_input_configdof, long int const *_nlist_begin, long int const *_nlist_end, double *_corr_begin, double *_corr_end) const
Calculate contribution to global correlations from one unit cell.
Definition: Clexulator.hh:552
size_type n_point_corr() const
Valid range for neighbor_ind argument to calc_point_corr.
Definition: Clexulator.hh:486
PermuteIterator from_canonical() const
std::vector< PermuteIterator > invariant_subgroup() const
MostDerived canonical_form() const
Index size() const
Number of sites in the ConfigDoF.
Definition: ConfigDoF.cc:11
std::map< DoFKey, LocalContinuousConfigDoFValues > const & local_dofs() const
Definition: ConfigDoF.cc:119
void set_global_dof(DoFKey const &_key, Eigen::Ref< const Eigen::VectorXd > const &_val)
Set global continuous DoF values.
Definition: ConfigDoF.cc:99
std::map< DoFKey, GlobalContinuousConfigDoFValues > const & global_dofs() const
Definition: ConfigDoF.cc:65
GlobalContinuousConfigDoFValues const & global_dof(DoFKey const &_key) const
Definition: ConfigDoF.cc:69
ConfigDoF & apply_sym(PermuteIterator const &it)
Definition: ConfigDoF.cc:182
int & occ(Index i)
Reference occupation value on site i.
Definition: ConfigDoF.cc:34
LocalContinuousConfigDoFValues const & local_dof(DoFKey const &_key) const
Definition: ConfigDoF.cc:124
Class for comparison of Configurations (with the same Supercell)
Eigen::VectorXd num_each_component() const
bool is_canonical() const
const ConfigDoF & configdof() const
const Access the DoF
static Configuration zeros(const std::shared_ptr< Supercell const > &_supercell_ptr)
void set_occupation(Eigen::Ref< const Eigen::VectorXi > const &_occupation)
Set occupant variables.
Configuration primitive() const
Return the primitive Configuration.
Eigen::VectorXi const & occupation() const
Occupant variables.
std::vector< Eigen::VectorXd > sublattice_composition() const
Configuration & apply_sym(const PermuteIterator &it)
Transform Configuration from PermuteIterator via *this = permute_iterator * *this.
ConfigIsEquivalent equal_to() const
bool eq_impl(const Configuration &B) const
operator== comparison of Configuration, via ConfigEqual
bool has_occupation() const
True if Configuration has occupation DoF.
Configuration(std::shared_ptr< Supercell const > const &_supercell_ptr)
Eigen::VectorXi num_each_molecule() const
Eigen::VectorXd true_composition() const
const Lattice & ideal_lattice() const
std::vector< PermuteIterator > point_group() const
Returns the point group that leaves the Configuration unchanged.
PermuteIterator find_translation() const
Returns a PermuteIterator corresponding to the first non-zero pure translation that maps the Configur...
std::vector< Eigen::VectorXi > sublat_num_each_molecule() const
std::vector< PermuteIterator > invariant_subgroup() const
Returns the subgroup of the Supercell factor group that leaves the Configuration unchanged.
Index linear_index(const UnitCellCoord &bijk) const
Return the linear index corresponding to integral coordinates.
ConfigInsertResult insert(bool primitive_only=false) const
Insert this configuration (in primitive & canonical form) in the database.
Supercell const * m_supercell
Pointer to the Supercell for this Configuration.
std::string generate_name_impl() const
Returns a Configuration name.
UnitCellCoord uccoord(Index site_l) const
Get the UnitCellCoord for a given linear site index.
const Molecule & mol(Index site_l) const
Molecule on site l.
Eigen::VectorXd param_composition() const
Returns parametric composition, as calculated using PrimClex::param_comp.
const int & occ(Index site_l) const
Occupant variable on site l.
void init_occupation()
Set occupant variables to background structure.
static std::pair< std::string, std::string > split_name(std::string configname)
Split configuration name string into scelname and config id.
int multiplicity() const
Get symmetric multiplicity, excluding translations.
ConfigCompare less() const
const Supercell & supercell() const
Get the Supercell for this Configuration.
ConfigDoF m_configdof
Degrees of Freedom.
Eigen::VectorXd composition() const
Configuration in_canonical_supercell() const
Returns the canonical form Configuration in the canonical Supercell.
void set_occ(Index site_l, int val)
Set occupant variable on site l.
std::string point_group_name() const
Returns the point group that leaves the Configuration unchanged.
int sublat(Index site_l) const
Get the basis site index for a given linear linear site index.
Index size() const
Returns number of sites, NOT the number of primitives that fit in here.
bool is_primitive() const
Check if this is a primitive Configuration.
bool operator<(const Configuration &B) const
Clear occupation.
std::vector< PermuteIterator > factor_group() const
Returns the subgroup of the Supercell factor group that leaves the Configuration unchanged.
std::string name() const
Definition: Named_impl.hh:14
A sparse container of ECI values and their corresponding orbit indices.
Definition: ECIContainer.hh:12
size_type size() const
Number of elements in the cluster.
Class for less than comparison of Configurations implemented via a ConfigTypeIsEqual class that also ...
Eigen::VectorXd const & values() const
Const access global DoF values.
SiteReference site_value(Index l)
Access site DoF value vector.
Eigen::MatrixXd const & values() const
Const access DoF values (prim DoF basis, matrix representing all sites)
Definition: Log.hh:48
void error(const std::string &what)
Definition: Log.hh:129
static const int standard
Definition: Log.hh:52
SupercellSymInfo const & sym_info() const
Reference the SupercellSymInfo containing the operations being pointed at.
Index factor_group_index() const
Return the supercell factor group index.
Index translation_index() const
Return the index into the supercell translation permutations.
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:55
ClexDescription const & clex(std::string clex_name) const
Get a ClexDescription by name.
Matrix3d rollup_E(Eigen::Ref< const VectorXd > const &_unrolled_E) const
const MasterSymGroup & factor_group() const
Definition: Structure.cc:107
const std::vector< size_type > & sites(size_type unitcell_index) const
const Access the list of sites neighboring a particular unit cell
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:51
Index sublat(Index linear_index) const
Return the sublattice index for a linear index.
Definition: Supercell.cc:165
Index linear_index(const Coordinate &coord, double tol=TOL) const
Given a Coordinate and tolerance, return linear index into Configuration.
Definition: Supercell.cc:183
UnitCellCoord uccoord(Index linear_index) const
Return the integral coordinates corresponding to a linear index.
Definition: Supercell.cc:209
const Lattice & lattice() const
The super lattice.
Definition: Supercell.cc:239
const SuperNeighborList & nlist() const
Returns the SuperNeighborList.
Definition: Supercell.cc:244
void set_primclex(PrimClex const *primclex_ptr) const
Use while transitioning Supercell to no longer need a PrimClex const *
Definition: Supercell.cc:136
Index num_sites() const
Definition: Supercell.cc:233
Index volume() const
Return number of primitive cells that fit inside of *this.
Definition: Supercell.cc:227
const Structure & prim() const
Definition: Supercell.cc:113
const SupercellSymInfo & sym_info() const
Definition: Supercell.cc:265
permute_const_iterator translate_end() const
End PermuteIterator over pure translational permutations.
permute_const_iterator permute_end() const
permute_const_iterator permute_begin() const
permute_const_iterator translate_begin() const
Begin PermuteIterator over pure translational permutations / Equivalent to permute_begin()
const vector_type & tau() const
Const access of the cartesian translation vector, 'tau'.
Definition: SymOp.hh:63
Lattice reduced_cell() const
Find the lattice vectors which give most compact unit cell Compactness is measured by how close lat_c...
Definition: Lattice.cc:302
Lattice & make_right_handed()
Flip c vector if it's on the wrong side of a-b plane – return (*this)
Definition: Lattice.cc:466
Class representing a Molecule.
Definition: Molecule.hh:93
Unit Cell Coordinates.
Unit Cell Indices.
double reference_energy(const Configuration &config)
Returns the reference energy, normalized per unit cell.
bool has_relaxed_magmom(const Configuration &_config)
Eigen::MatrixXd relaxed_forces(const Configuration &_config)
relaxed forces of configuration, determined from DFT (eV/Angstr.), as a 3xN matrix
bool has_volume_relaxation(const Configuration &_config)
double formation_energy(const Configuration &config)
Returns the formation energy, normalized per unit cell.
bool has_reference_energy(const Configuration &_config)
double formation_energy_per_species(const Configuration &config)
Returns the formation energy, normalized per species.
double clex_formation_energy_per_species(const Configuration &config)
Returns the formation energy, normalized per species.
double atomic_deformation(const Configuration &_config)
Cost function that describes the degree to which basis sites have relaxed.
Eigen::VectorXi num_each_molecule(const ConfigDoF &configdof, const Supercell &scel)
Returns num_each_molecule(molecule_type), where 'molecule_type' is ordered as Structure::get_struc_mo...
Eigen::VectorXd correlations(const Configuration &config, Clexulator const &clexulator)
Returns correlations using 'clexulator'.
double clex_formation_energy(const Configuration &config)
Returns the formation energy, normalized per unit cell.
Eigen::VectorXd corr_contribution(Index linear_unitcell_index, const Configuration &config, Clexulator const &clexulator)
Returns correlation contribution from a single unit cell, not normalized.
Eigen::VectorXd comp(const Configuration &config)
Returns parametric composition, as calculated using PrimClex::param_comp.
Configuration closest_setting(const Configuration &_config1, const Configuration &_config2)
Configuration sub_configuration(std::shared_ptr< Supercell const > sub_scel_ptr, const Configuration &super_config, const UnitCell &origin=UnitCell(0, 0, 0))
Returns the sub-configuration that fills a particular Supercell.
double rms_force(const Configuration &_config)
Root-mean-square forces of relaxed configurations, determined from DFT (eV/Angstr....
bool has_lattice_deformation(const Configuration &_config)
bool has_rms_force(const Configuration &_config)
double n_species(const Configuration &config)
Returns the total number species per unit cell.
bool is_primitive(const Configuration &_config)
returns true if _config describes primitive cell of the configuration it describes
double volume_relaxation(const Configuration &_config)
Change in volume due to relaxation, expressed as the ratio V/V_0.
double reference_energy_per_species(const Configuration &config)
Returns the reference energy, normalized per species.
Eigen::MatrixXd gradcorrelations(const Configuration &config, Clexulator const &clexulator, DoFKey &key)
Returns gradient correlations using 'clexulator', with respect to DoF 'dof_type'.
Eigen::VectorXd comp_n(const Configuration &config)
Returns the composition, as number of each species per unit cell.
IntegralCluster config_diff(const Configuration &_config1, const Configuration &_config2)
Returns an Integral Cluster representing the perturbed sites between the configs.
double relaxed_magmom(const Configuration &_config)
Returns the relaxed magnetic moment, normalized per unit cell.
Eigen::VectorXd site_frac(const Configuration &config)
Returns the composition as site fraction, in the order of Structure::get_struc_molecule.
Configuration make_configuration(const PrimClex &primclex, std::string name)
Make Configuration from name string.
double lattice_deformation(const Configuration &_config)
Cost function that describes the degree to which lattice has relaxed.
double energy(const Configuration &config)
Returns the energy, normalized per unit cell.
double n_vacancy(const Configuration &config)
Returns the vacancy composition, as number per unit cell.
Configuration config_clip(const Configuration &_config, const Configuration &_bg, IntegralCluster &_clust)
Returns a Configuration with the sites in _clust clipped from _config and placed in _bg.
Eigen::VectorXd point_corr(Index linear_unitcell_index, Index neighbor_index, const Configuration &config, Clexulator const &clexulator)
Returns point correlations from a single site, normalized by cluster orbit size.
double energy_per_species(const Configuration &config)
Returns the energy, normalized per species.
bool has_formation_energy(const Configuration &_config)
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...
bool has_atomic_deformation(const Configuration &_config)
bool is_canonical(const Configuration &_config)
returns true if no symmetry transformation applied to _config will increase its lexicographic order
bool has_relaxed_mag_basis(const Configuration &_config)
double relaxed_magmom_per_species(const Configuration &_config)
Returns the relaxed magnetic moment, normalized per species.
bool has_energy(const Configuration &_config)
std::string to_string(ENUM val)
Return string representation of enum class.
Definition: io_traits.hh:172
Eigen::CwiseUnaryOp< decltype(Local::iround_l< typename Derived::Scalar >), const Derived > iround(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd to Eigen::MatrixXi.
bool is_vacancy(const std::string &name)
A vacancy is any Specie/Molecule with (name == "VA" || name == "va" || name == "Va")
Definition: Molecule.hh:187
std::string const & name() const
Designated name of Molecule (may be unrelated to constituent species)
Definition: Molecule.hh:117
DB::Database< T > & db() const
Definition: PrimClex.cc:302
ProjectSettings & settings()
Definition: PrimClex.cc:224
ECIContainer const & eci(const ClexDescription &key) const
Definition: PrimClex.cc:406
Clexulator clexulator(std::string const &basis_set_name) const
Definition: PrimClex.cc:366
const PrimType & prim() const
const Access to primitive Structure
Definition: PrimClex.cc:262
std::vector< std::string > struc_molecule_name(BasicStructure const &_struc)
Returns an Array of each possible Molecule in this Structure.
std::shared_ptr< Supercell > make_shared_supercell(const PrimClex &primclex, std::string name)
Definition: Supercell.cc:433
std::string scelname(const Structure &prim, const Lattice &superlat)
Make supercell name name [deprecated].
Definition: Supercell.cc:497
Supercell & apply(const SymOp &op, Supercell &scel)
Apply symmetry operation to Supercell.
Definition: Supercell.cc:357
ConfigIO::GenericConfigFormatter< jsonParser > config()
Definition: ConfigIO.cc:777
ConfigIO::GenericConfigFormatter< std::string > configname()
Constructs DataFormmaterDictionary containing all Configuration DatumFormatters.
Definition: ConfigIO.cc:563
Configuration in_canonical_supercell(Configuration const &configuration, Database< Supercell > &supercell_db)
Returns the canonical form Configuration in the canonical Supercell.
ConfigInsertResult make_canonical_and_insert(Configuration const &configuration, Database< Supercell > &supercell_db, Database< Configuration > &configuration_db, bool primitive_only)
Insert this configuration (in primitive & canonical form) in the database.
GenericVectorXdScelFormatter lattice()
Definition: SupercellIO.cc:266
SharedPrimFormatter< jsonParser > primitive()
VectorXdSupercellSymInfoFormatter supercell_lattice()
bool is_equivalent(const Lattice &ref_lattice, const Lattice &other)
Check if ref_lattice = other*U, where U is unimodular.
Lattice replace_vector(const Lattice &lat, const Eigen::Vector3d &new_vector, double tol)
Definition: Lattice.cc:812
std::pair< OpIterator, Eigen::Matrix3d > is_equivalent_superlattice(const Object &scel, const Object &unit, OpIterator begin, OpIterator end, double tol)
Definition: SymTools.hh:110
Main CASM namespace.
Definition: APICommand.hh:8
Eigen::MatrixXd MatrixXd
std::ostream & operator<<(std::ostream &_stream, const FormattedPrintable &_formatted)
Configuration fill_supercell(Configuration const &motif, std::shared_ptr< Supercell const > const &shared_supercell)
SymGroup make_sym_group(const PermuteIteratorContainer &container, const Lattice &supercell_lattice)
Returns a SymGroup generated from a container of PermuteIterator.
MappingNode copy_apply(PermuteIterator const &_it, MappingNode const &_node, bool transform_cost_mat=true)
Reorders the permutation and compounds the spatial isometry (rotation.
std::string DoFKey
Definition: DoFDecl.hh:7
GenericConfigCompare< Configuration, ConfigIsEquivalent > ConfigCompare
DoFSpecsType const & get(DoFKey const &key, BasisFunctionSpecs const &basis_function_specs)
GenericDatumFormatter< std::string, DataObject > name()
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:16
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value)
Definition: algorithm.hh:83
ConfigDoF make_configdof(Structure const &prim, Index volume)
Construct zero-valued ConfigDoF.
std::vector< std::vector< Index > > make_index_converter(const Structure &struc, std::vector< xtal::Molecule > mol_list)
Definition: Structure.cc:322
T * end_ptr(std::vector< T > &container)
Return pointer one past end of vector. Equivalent to convainer.data()+container.size()
Definition: algorithm.hh:142
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Eigen::VectorXd VectorXd
Log & err_log()
Definition: Log.hh:426
pair_type ref
Definition: settings.cc:144
pair_type eci
Definition: settings.cc:146
PrimClex * primclex
Definition: settings.cc:135
pair_type calctype
Definition: settings.cc:143
Holds results of Configuration::insert.
std::map< std::string, Eigen::MatrixXd > site
Operations that transform a canonical primitive configuration to any equivalent.
std::string name() const
Configuration prim_canon_config
PermuteIterator from_canonical_config
Eigen::Matrix3i transf_mat
RefToCanonicalPrim(const Configuration &_config)
Get operations that transform canonical primitive to this.