CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
Supercell.cc
Go to the documentation of this file.
1 #include "casm/clex/Supercell.hh"
2 
3 #include <math.h>
4 #include <map>
5 #include <vector>
6 #include <stdlib.h>
7 
8 //#include "casm/clusterography/HopCluster.hh"
9 #include "casm/clex/PrimClex.hh"
11 #include "casm/clex/Clexulator.hh"
12 
13 namespace CASM {
14 
15  //Given a Site and tolerance, return linear index into Configuration
16  // This may be slow, first converts Site -> UnitCellCoord,
17  // then finds UnitCellCoord in config_index_to_bijk
18  Index Supercell::get_linear_index(const Site &site, double tol) const {
19  //std::cout << "site: " << site << " UCC: " << get_prim().get_unit_cell_coord(site, tol) << std::endl;
20  Site tsite(site);
21  tsite.within();
22  return find(get_prim().get_unit_cell_coord(tsite, tol));
23  };
24 
25  /*****************************************************************/
26 
27  //Given a Coordinate and tolerance, return linear index into Configuration
28  // This may be slow, first converts Coordinate -> UnitCellCoord,
29  // then finds UnitCellCoord in config_index_to_bijk
30  Index Supercell::get_linear_index(const Coordinate &coord, double tol) const {
31  //std::cout << "coord: " << coord << " UCC: " << get_prim().get_unit_cell_coord(coord, tol) << std::endl;
32  Coordinate tcoord(coord);
33  tcoord.within();
34  return find(get_prim().get_unit_cell_coord(tcoord, tol));
35  };
36 
37  /*****************************************************************/
38 
39  Index Supercell::find(const UnitCellCoord &bijk) const {
40  return bijk[0] * volume() + m_prim_grid.find(bijk);
41  }
42 
43  /*****************************************************************/
44 
46  Coordinate tcoord(m_prim_grid.coord(bijk, SCEL));
47  tcoord.cart() += (*primclex).get_prim().basis[bijk[0]].cart();
48  return tcoord;
49  };
50 
51  /*****************************************************************/
52 
54  Coordinate tcoord(m_prim_grid.coord(l % volume(), SCEL));
55  tcoord.cart() += (*primclex).get_prim().basis[get_b(l)].cart();
56  return tcoord;
57  };
58 
59  /*****************************************************************/
60 
62  Array<int> max_allowed;
63 
64  // Figures out the maximum number of occupants in each basis site, to initialize counter with
65  for(Index i = 0; i < get_prim().basis.size(); i++) {
66  max_allowed.append(Array<int>(volume(), get_prim().basis[i].site_occupant().size() - 1));
67  }
68  //std::cout << "max_allowed_occupation is: " << max_allowed << "\n\n";
69  return max_allowed;
70  }
71 
72  /*****************************************************************/
73 
74  const Structure &Supercell::get_prim() const {
75  return primclex->get_prim();
76  }
77 
80 
81  // if any additions to the prim nlist, must update the super nlist
83  m_nlist.unique().reset();
84  }
85 
86  // lazy construction of neighbor list
87  if(!m_nlist) {
89  m_nlist = notstd::make_cloneable<SuperNeighborList>(
92  );
93  }
94  return *m_nlist;
95  };
96 
97  /*****************************************************************/
98 
99  // begin and end iterators for iterating over configurations
101  return config_iterator(primclex, m_id, 0);
102  }
103 
105  return ++config_iterator(primclex, m_id, config_list.size() - 1);
106  }
107 
108  // begin and end const_iterators for iterating over configurations
110  return config_const_iterator(primclex, m_id, 0);
111  }
112 
114  return ++config_const_iterator(primclex, m_id, config_list.size() - 1);
115  }
116 
123  std::string Supercell::get_name() const {
124  if(m_name.empty()) {
125  _generate_name();
126  }
127  return m_name;
128  };
129 
130  /*****************************************************************/
131 
133  if(!m_factor_group.size())
135  return m_factor_group;
136  }
137 
138  /*****************************************************************/
139 
140  // permutation_symrep() populates permutation symrep if needed
143  }
144  /*****************************************************************/
145 
146  // PrimGrid populates translation permutations if needed
149  }
150 
151  /*****************************************************************/
152 
153  // PrimGrid populates translation permutations if needed
156  }
157 
158  /*****************************************************************/
159 
162  return permute_begin();
163  }
164 
165  /*****************************************************************/
166 
169  return permute_begin().begin_next_fg_op();
170  }
171 
172  /*****************************************************************/
173  /* //Example usage case:
174  * Supercell my_supercell;
175  * Configuration my_config(my_supercell, configuration_info);
176  * ConfigDoF my_dof=my_config.configdof();
177  * my_dof.is_canonical(my_supercell.permute_begin(),my_supercell.permute_end());
178  */
180  return permute_it(0, 0); // starting indices
181  }
182 
183  /*****************************************************************/
184 
186  return permute_it(factor_group().size(), 0); // one past final indices
187  }
188 
189  /*****************************************************************/
190 
193  m_prim_grid,
194  fg_index, trans_index); // one past final indices
195  }
196 
197  /*****************************************************************/
198 
199  //Printing config_index_to_bijk
200  void Supercell::print_bijk(std::ostream &stream) {
201  for(Index i = 0; i < num_sites(); i++) {
202  stream << uccoord(i);
203  }
204  }
205 
206  //*******************************************************************************
210  //*******************************************************************************
211  void Supercell::enumerate_perturb_configurations(const std::string &background, fs::path CSPECS, double tol, bool verbose, bool print) {
212  Structure background_struc;
213  fs::ifstream file(background);
214  background_struc.read(file);
215  enumerate_perturb_configurations(background_struc, CSPECS, tol, verbose, print);
216  }
217 
218  //*******************************************************************************
224  //*******************************************************************************
225  void Supercell::enumerate_perturb_configurations(Configuration background_config, fs::path CSPECS, double tol, bool verbose, bool print) {
226  // Algorithm:
227  // 1) generate orbitree in background
228  // 2) generate background config
229  // 3) for each orbit:
230  // perturb background config with decorated prototype cluster
231  // check if in config list
232  // NOTE: This can be done much faster using permutation arithmetic
233  if(verbose) std::cout << "begin enumerate_perturb_configurations" << std::endl;
234 
235  // should generate the background_tree from the supercell-sized background structure
236  // this gets the right symmetry for the combination of perturbation and supercell shape
237 
238  if(verbose) std::cout << "Generate background structure" << std::endl;
239  Structure background_scel = superstructure(background_config);
240 
241  // generate the background config & orbitree
242  // std::cout << "generate background config and orbitree" << std::endl;
243  SiteOrbitree background_tree(background_scel.lattice(), primclex->crystallography_tol());
244 
245  //fs::ifstream cspecsfile(CSPECS);
246  //background_tree.read_CSPECS(cspecsfile);
247  //cspecsfile.close();
248 
249  jsonParser json(CSPECS);
250  background_tree.min_num_components = 2;
251  background_tree.min_length = CASM::TOL;
252 
253  background_tree.max_length.clear();
254  auto update_max_length = [&](int branch, double max_length) {
255  while(branch > background_tree.max_length.size() - 1) {
256  background_tree.max_length.push_back(0.0);
257  }
258  background_tree.max_length[branch] = max_length;
259  };
260 
261  for(auto it = json["orbit_branch_specs"].cbegin(); it != json["orbit_branch_specs"].cend(); ++it) {
262  update_max_length(std::stoi(it.name()), it->find("max_length")->get<double>());
263  }
264  background_tree.max_num_sites = background_tree.max_length.size() - 1;
265 
266 
267 
268  if(verbose) std::cout << "Generate background orbitree" << std::endl;
269  background_tree.generate_orbitree(background_scel);
270 
271  if(verbose) std::cout << "background_config: " << background_config.name() << std::endl;
272 
273  // for now, don't do anything with these here
274  Array< Array< Array<Index> > > perturb_config_index;
275  Array< Array< Array<permute_const_iterator> > > perturb_config_symop_index;
276 
277  if(verbose) std::cout << "Enumerate perturb configurations" << std::endl;
278 
279  jsonParser jsonsrc = jsonParser::object();
280  jsonsrc["supercell_name"] = get_name();
281  jsonsrc["configid"] = background_config.get_id();
282 
283  enumerate_perturb_configurations(background_config, background_tree, perturb_config_index, perturb_config_symop_index, jsonsrc, tol);
284 
285  if(verbose) {
286  for(Index nb = 0; nb < perturb_config_index.size(); nb++) {
287  std::cout << " Branch: " << nb << std::endl;
288 
289  for(Index no = 0; no < perturb_config_index[nb].size(); no++) {
290  std::cout << " Orbit: " << no << std::endl;
291  background_tree.prototype(nb, no).print_decorated_sites(std::cout, 8, '\n');
292 
293  for(Index nd = 0; nd < perturb_config_index[nb][no].size(); nd++) {
294  std::cout << " config_index: " << perturb_config_index[nb][no][nd] << std::endl;
295  }
296  }
297  }
298  }
299 
300  if(print) {
301  if(verbose) std::cout << "Print info" << std::endl;
302 
303  // write in supercells/scel_name/config_name.perturb
304  try {
305  fs::create_directory("training_data");
306  }
307  catch(const fs::filesystem_error &ex) {
308  std::cerr << "Error in Supercell::enumerate_perturb_configurations()." << std::endl;
309  std::cerr << ex.what() << std::endl;
310  }
311 
312  try {
313  fs::create_directory(get_path());
314  }
315  catch(const fs::filesystem_error &ex) {
316  std::cerr << "Error in Supercell::enumerate_perturb_configurations()." << std::endl;
317  std::cerr << ex.what() << std::endl;
318  }
319 
320  //const fs::path config_path = background_config.get_path() += ".perturb"; boost version clash;
321  std::string pathstr = background_config.get_path().filename().string() + ".perturb"; //make string for only the filename (myfile.perturb)
322  const fs::path config_path = background_config.get_path().remove_filename() /= pathstr; //remve myfile from path and add myfile.perturb instead
323 
324 
325  try {
326  fs::create_directory(config_path);
327 
328  // write CSPECS, FCLUST, PERTURB.json
329  // - overwrite if necessary
330 
331  // write CSPECS
332  {
333  if(fs::exists(config_path / "CSPECS"))
334  fs::remove(config_path / "CSPECS");
335  fs::copy(fs::path(CSPECS), config_path / "CSPECS");
336  }
337 
338  // write CLUST
339  {
340  if(fs::exists(config_path / "CLUST"))
341  fs::remove(config_path / "CLUST");
342 
343  background_tree.write_proto_clust((config_path / "CLUST").string());
344 
345  }
346 
347  // write FCLUST
348  {
349  if(fs::exists(config_path / "FCLUST"))
350  fs::remove(config_path / "FCLUST");
351 
352  background_tree.write_full_clust((config_path / "FCLUST").string());
353 
354  }
355 
356  // write PERTURB.json
357  {
358  if(fs::exists(config_path / "PERTURB.json"))
359  fs::remove(config_path / "PERTURB.json");
360 
361  fs::ofstream file(config_path / "PERTURB.json");
362 
363  print_PERTURB_json(file, background_config, perturb_config_index, perturb_config_symop_index, false);
364  }
365 
366  }
367  catch(const fs::filesystem_error &ex) {
368  std::cerr << "Error in Supercell::enumerate_perturb_configurations()." << std::endl;
369  std::cerr << ex.what() << std::endl;
370  }
371  }
372 
373  if(verbose) std::cout << "finish enumerate_perturb_configurations" << std::endl;
374 
375  }
376 
377  //*******************************************************************************
382  //*******************************************************************************
383  void Supercell::enumerate_perturb_configurations(const Structure &background, fs::path CSPECS, double tol, bool verbose, bool print) {
384 
385  Configuration background_config = configuration(background);
386  enumerate_perturb_configurations(background_config, CSPECS, tol, verbose, print);
387 
388  };
389 
390  //*******************************************************************************
406  //*******************************************************************************
408  const SiteOrbitree &background_tree,
409  Array< Array< Array<Index> > > &config_index,
410  Array< Array< Array<permute_const_iterator> > > &config_symop_index,
411  jsonParser &jsonsrc,
412  double tol) {
413 
414  //std::cout << "begin enumerate_perturb_configurations() ****" << std::endl;
415 
416  /* primitive pointer no longer exists
417  if((*primclex).get_prim().lattice.primitive != background_tree.lattice.primitive) {
418  std::cerr << "Error in Supercell::enumerate_perturb_configurations." << std::endl;
419  std::cerr << " 'background_tree' lattice primitive is not primclex->prim lattice primitive" << std::endl;
420  exit(1);
421  }
422  */
423 
424  // perturb_list.json: json["background_id"]["branch"]["orbit"][{decor = [linear_indices], id = config_id}]
425 
426 
427  Configuration config = background_config;
428  config.set_selected(false);
429 
430  // variables used for generating perturb configs
431  Array< Array<int> > decor_map;
432  Array<int> linear_indices;
433  Array<int> orig_occ;
434  Index index;
436 
437  config_index.resize(background_tree.size());
438  config_symop_index.resize(background_tree.size());
439 
440 
441  // for each branch in 'background_tree'
442  //std::cout << "loop over background_tree" << std::endl;
443  for(Index nb = 0; nb < background_tree.size(); nb++) {
444 
445  //std::cout << "branch " << nb << std::endl;
446  config_index[nb].resize(background_tree[nb].size());
447  config_symop_index[nb].resize(background_tree[nb].size());
448 
449  // for each orbit
450  for(Index no = 0; no < background_tree[nb].size(); no++) {
451  //std::cout << "\n\n---------------------" << std::endl;
452  //std::cout << "branch: " << nb << " orbit " << no << std::endl;
453 
454 
455  // get decor_map for prototype
456  //std::cout << "get decor_map" << std::endl;
457  decor_map = background_tree[nb][no].prototype.get_full_decor_map();
458 
459  // determine linear_index for cluster sites
460  //std::cout << "get linear_indices and orig_occ" << std::endl;
461  linear_indices.clear();
462  orig_occ.clear();
463  for(Index i = 0; i < background_tree[nb][no].prototype.size(); i++) {
464  //std::cout << " Site: " << i << " :: " << background_tree[nb][no].prototype[i] << std::endl;
465  linear_indices.push_back(get_linear_index(Coordinate(background_tree[nb][no].prototype[i]), tol));
466  //std::cout << " linear_index: " << linear_indices.back() << std::endl;
467  //std::cout << " frac_coord: " << frac_coord( config_index_to_bijk[linear_indices.back()]) << std::endl;
468  orig_occ.push_back(config.occ(linear_indices[i]));
469 
470  }
471 
472  //Generate new clusters with different decorations using decor_map
473  //std::cout << "decorate" << std::endl;
474  for(Index i = 0; i < decor_map.size(); i++) {
475  //std::cout << "decor_map " << i << ": " << decor_map[i] << std::endl;
476  // set occupants
477  for(Index j = 0; j < decor_map[i].size(); j++) {
478  config.set_occ(linear_indices[j], decor_map[i][j]);
479  }
480 
481  // At this point, 'config' is the perturbed config (using prototype & decor_map[i])
482 
483  jsonsrc["perturbation"].put_obj();
484  jsonsrc["perturbation"]["branch"] = nb;
485  jsonsrc["perturbation"]["orbit"] = no;
486  jsonsrc["perturbation"]["decor"] = decor_map[i];
487 
488  config.set_source(jsonsrc);
489  add_config(config, index, permute_it);
490  //std::cout << "add_config: " << index << " result: " << result << " nb: " << nb << " no: " << no << std::endl;
491 
492 
493  config_index[nb][no].push_back(index);
494  config_symop_index[nb][no].push_back(permute_it);
495 
496  //std::cout << "next" << std::endl << std::endl;
497  }
498 
499  // reset 'config' to original occupants
500  //std::cout << "reset background" << std::endl;
501  for(Index i = 0; i < orig_occ.size(); i++) {
502  config.set_occ(linear_indices[i], orig_occ[i]);
503  }
504 
505  //std::cout << "next orbit" << std::endl;
506 
507  }
508  }
509 
510  //std::cout << "finish enumerate_perturb_configurations() ****" << std::endl;
511 
512  };
513 
514  //*******************************************************************************
521  //*******************************************************************************
522  bool Supercell::contains_config(const Configuration &config) const {
523  Index index;
524  return contains_config(config, index);
525  };
526 
527  //*******************************************************************************
537  //*******************************************************************************
538  bool Supercell::contains_config(const Configuration &config, Index &index) const {
539  auto res = m_config_map.find(&config);
540  if(res == m_config_map.end()) {
541  index = config_list.size();
542  return false;
543  }
544  index = res->second;
545  return true;
546  };
547 
548  //*******************************************************************************
550  auto res = m_config_map.find(&config);
551  if(res == m_config_map.end()) {
552  return config_cend();
553  }
554  return config_const_iterator(&get_primclex(), get_id(), res->second);
555  }
556 
557  //*******************************************************************************
566  //*******************************************************************************
567 
568  bool Supercell::add_config(const Configuration &config) {
569  Index index;
571  return add_config(config, index, permute_it);
572  }
573 
575  // 'permut_it' stores operation that takes 'config' to its canonical form
576  permute_it = config.to_canonical();
577 
578  // std::cout << " config: " << config.occupation() << std::endl;
579  // std::cout << " canon: " << canon_config.occupation() << std::endl;
580 
581  return add_canon_config(copy_apply(permute_it, config), index);
582  }
583 
584  //*******************************************************************************
589  //*******************************************************************************
590  bool Supercell::add_canon_config(const Configuration &canon_config, Index &index) {
591 
592  // Add 'canon_config' to 'config_list' if it doesn't already exist
593  // store it's index into 'config_list' in 'config_list_index'
594  //std::cout << "check if canon_config is in config_list" << std::endl;
595  if(!contains_config(canon_config, index)) {
596  //std::cout << "new config" << std::endl;
597  _add_canon_config(canon_config);
598  return true;
599  //std::cout << " added" << std::endl;
600  }
601  else {
602  config_list[index].push_back_source(canon_config.source());
603  }
604  return false;
605  }
606 
607  //*******************************************************************************
608 
610  std::pair<Supercell::config_const_iterator, bool>
612  return insert_canon_config(config.canonical_form());
613  }
614 
615  //*******************************************************************************
616 
618  std::pair<Supercell::config_const_iterator, bool>
620  Index index;
621  std::pair<Supercell::config_const_iterator, bool> res;
622  res.second = false;
623  if(!contains_config(canon_config, index)) {
624  _add_canon_config(canon_config);
625  index = config_list.size() - 1;
626  res.second = true;
627  }
628  res.first = config_const_iterator(&get_primclex(), get_id(), index);
629  return res;
630  }
631 
632  //*******************************************************************************
637  //*******************************************************************************
638  void Supercell::_add_canon_config(const Configuration &canon_config) {
639 
640  if(this != &canon_config.get_supercell()) {
641  throw std::runtime_error("Error adding Configuration to Supercell: Supercell mismatch");
642  }
643  //std::cout << "new config" << std::endl;
644  config_list.push_back(canon_config);
645  config_list.back().set_id(config_list.size() - 1);
646  m_config_map.insert(
647  std::make_pair(&config_list.back(),
648  boost::lexical_cast<Index>(config_list.back().get_id())));
649  config_list.back().set_selected(false);
650  }
651 
652  //*******************************************************************************
653 
655 
656  // Provide an error check
657  if(config_list.size() != 0) {
658  std::cerr << "Error in Supercell::read_configuration." << std::endl;
659  std::cerr << " config_list.size() != 0, only use this once" << std::endl;
660  exit(1);
661  }
662 
663  if(!json.contains("supercells")) {
664  return;
665  }
666 
667  if(!json["supercells"].contains(get_name())) {
668  return;
669  }
670 
671  // Read all configurations for this supercell. They should be numbered sequentially, so read until not found.
672  Index configid = 0;
673  while(true) {
674  std::stringstream ss;
675  ss << configid;
676 
677  if(json["supercells"][get_name()].contains(ss.str())) {
678  config_list.push_back(Configuration(json, *this, configid));
679  m_config_map.insert(
680  std::make_pair(&config_list.back(),
681  boost::lexical_cast<Index>(config_list.back().get_id())));
682  }
683  else {
684  return;
685  }
686  configid++;
687  }
688  }
689 
690 
691  //*******************************************************************************
692 
693  //Copy constructor is needed for proper initialization of m_prim_grid
695  primclex(RHS.primclex),
696  real_super_lattice(RHS.real_super_lattice),
697  recip_prim_lattice(RHS.recip_prim_lattice),
698  m_prim_grid((*primclex).get_prim().lattice(), real_super_lattice, (*primclex).get_prim().basis.size()),
699  recip_grid(recip_prim_lattice, (*primclex).get_prim().lattice().get_reciprocal()),
700  m_name(RHS.m_name),
701  m_nlist(RHS.m_nlist),
702  m_canonical(nullptr),
703  config_list(RHS.config_list),
704  transf_mat(RHS.transf_mat),
705  scaling(RHS.scaling),
706  m_id(RHS.m_id) {
707  }
708 
709  //*******************************************************************************
710 
711  Supercell::Supercell(PrimClex *_prim, const Eigen::Ref<const Eigen::Matrix3i> &transf_mat_init) :
712  primclex(_prim),
713  real_super_lattice((*primclex).get_prim().lattice().lat_column_mat() * transf_mat_init.cast<double>()),
714  recip_prim_lattice(real_super_lattice.get_reciprocal()),
715  m_prim_grid((*primclex).get_prim().lattice(), real_super_lattice, (*primclex).get_prim().basis.size()),
716  recip_grid(recip_prim_lattice, (*primclex).get_prim().lattice().get_reciprocal()),
717  m_canonical(nullptr),
718  transf_mat(transf_mat_init) {
719  scaling = 1.0;
720  // fill_reciprocal_supercell();
721  }
722 
723  //*******************************************************************************
724 
725  Supercell::Supercell(PrimClex *_prim, const Lattice &superlattice) :
726  primclex(_prim),
727  //real_super_lattice((get_prim()).lattice().lat_column_mat()*transf_mat),
728  real_super_lattice(superlattice),
729  recip_prim_lattice(real_super_lattice.get_reciprocal()),
730  m_prim_grid((*primclex).get_prim().lattice(), real_super_lattice, (*primclex).get_prim().basis.size()),
731  recip_grid(recip_prim_lattice, (*primclex).get_prim().lattice().get_reciprocal()),
732  m_canonical(nullptr),
733  transf_mat(primclex->calc_transf_mat(superlattice)) {
734  /*std::cerr << "IN SUPERCELL CONSTRUCTOR:\n"
735  << "transf_mat is\n" << transf_mat << '\n'
736  << "prim lattice is \n";
737  (*primclex).get_prim().lattice.print(std::cerr);
738  std::cerr << "\nSupercell Lattice is\n";
739  real_super_lattice.print(std::cerr);
740  std::cerr << "\nORIGINAL Supercell Lattice is\n";
741  superlattice.print(std::cerr);
742 
743  std::cerr << "\nlat_column_mat() is\n" << (*primclex).get_prim().lattice.lat_column_mat()
744  << "\n and product with transf_mat is \n" << (*primclex).get_prim().lattice.lat_column_mat()*transf_mat << "\n";
745  */
746  scaling = 1.0;
747 
748  }
749 
750  //*******************************************************************************
759  for(Index c = 0; c < config_list.size(); c++) {
760  config_list[c].write(json);
761  }
762  return json;
763  }
764 
765 
766  //*******************************************************************************
774  //*******************************************************************************
775  void Supercell::print_PERTURB_json(std::ofstream &file,
776  const Configuration &background_config,
777  const Array< Array< Array<Index > > > &perturb_config_index,
778  const Array< Array< Array<permute_const_iterator> > > &perturb_config_symop_index,
779  bool print_config_name) const {
780 
782 
783  json["supercell_name"] = get_name();
784  if(print_config_name) {
785  json["config"] = background_config.name();
786  }
787  else {
788  json["configid"] = background_config.get_id();
789  }
790  json["perturbations"] = jsonParser::array();
791 
792  for(Index nb = 0; nb < perturb_config_index.size(); nb++) {
793  for(Index no = 0; no < perturb_config_index[nb].size(); no++) {
794  for(Index nd = 0; nd < perturb_config_index[nb][no].size(); nd++) {
795 
796  jsonParser jsonobj = jsonParser::object();
797 
798  jsonobj["orbitbranch"] = nb;
799  jsonobj["orbit"] = no;
800 
801  if(print_config_name) {
802  jsonobj["config"] = get_config(perturb_config_index[nb][no][nd]).name();
803  }
804  else {
805  jsonobj["configid"] = perturb_config_index[nb][no][nd];
806  }
807  jsonobj["symop"] = perturb_config_symop_index[nb][no][nd];
808 
809  json["perturbations"].push_back(jsonobj);
810 
811  }
812  }
813  }
814 
815  json.print(file);
816 
817  }
818 
819  //***********************************************************
820 
824  return;
825  }
826 
827  //***********************************************************
828 
830  if(!m_perm_symrep_ID.empty()) {
831  std::cerr << "WARNING: In Supercell::generate_permutations(), but permutations data already exists.\n"
832  << " It will be overwritten.\n";
833  }
835  //m_trans_permute = m_prim_grid.make_translation_permutations(basis_size()); <--moved to PrimGrid
836 
837  /*
838  std::cerr << "For SCEL " << " -- " << get_name() << " Translation Permutations are:\n";
839  for(int i = 0; i < m_trans_permute.size(); i++)
840  std::cerr << i << ": " << m_trans_permute[i].perm_array() << "\n";
841 
842  std::cerr << "For SCEL " << " -- " << get_name() << " factor_group Permutations are:\n";
843  for(int i = 0; i < m_factor_group.size(); i++){
844  std::cerr << "Operation " << i << ":\n";
845  m_factor_group[i].print(std::cerr,FRAC);
846  std::cerr << '\n';
847  std::cerr << i << ": " << m_factor_group[i].get_permutation_rep(m_perm_symrep_ID)->perm_array() << '\n';
848 
849  }
850  std:: cerr << "End permutations for SCEL " << get_name() << '\n';
851  */
852 
853  return;
854  }
855 
856  //***********************************************************
857 
859  //std::cout << "begin _generate_name()" << std::endl;
861  }
862 
863  //***********************************************************
864 
866  return get_primclex().get_path() / "training_data" / get_name();
867  }
868 
869  /*
870  * Run through the configuration list and count how many of them
871  * have been selected then return value.
872  */
873 
876  for(Index c = 0; c < config_list.size(); c++) {
877  if(config_list[c].selected()) {
878  amount_selected++;
879  }
880  }
881  return amount_selected;
882  }
883 
884  //***********************************************************
885 
886  bool Supercell::is_canonical() const {
888  get_prim().point_group(),
889  get_primclex().crystallography_tol());
890  }
891 
892  //***********************************************************
893 
896  get_prim().point_group(),
897  get_primclex().crystallography_tol());
898  }
899 
900  //***********************************************************
901 
904  get_prim().point_group(),
905  get_primclex().crystallography_tol());
906  }
907 
908  //***********************************************************
909 
911  if(!m_canonical) {
913  get_primclex().add_supercell(get_real_super_lattice()));
914  }
915  return *m_canonical;
916  }
917 
918  //***********************************************************
923  //***********************************************************
924  bool Supercell::is_supercell_of(const Structure &structure) const {
925  Eigen::Matrix3d mat;
926  return is_supercell_of(structure, mat);
927  };
928 
929  //***********************************************************
934  //***********************************************************
935  bool Supercell::is_supercell_of(const Structure &structure, Eigen::Matrix3d &mat) const {
936  Structure tstruct = structure;
937  SymGroup point_group;
938  tstruct.lattice().generate_point_group(point_group);
939  //if(real_super_lattice.is_supercell_of(tstruct.lattice, tstruct.factor_group().point_group(), mat)) {
940 
941  if(real_super_lattice.is_supercell_of(tstruct.lattice(), point_group, mat)) {
942 
943  return true;
944  }
945  return false;
946  };
947 
948  //***********************************************************
954  //***********************************************************
955  Configuration Supercell::configuration(const BasicStructure<Site> &structure_to_config, double tol) {
956  //Because the user is a fool and the supercell may not be a supercell (This still doesn't check the basis!)
957  Eigen::Matrix3d transmat;
958  if(!structure_to_config.lattice().is_supercell_of(get_prim().lattice(), get_prim().factor_group(), transmat)) {
959  std::cerr << "ERROR in Supercell::configuration" << std::endl;
960  std::cerr << "The provided structure is not a supercell of the PRIM. Tranformation matrix was:" << std::endl;
961  std::cerr << transmat << std::endl;
962  exit(881);
963  }
964 
965  std::cerr << "WARNING in Supercell::config(): This routine has not been tested on relaxed structures using 'tol'" << std::endl;
966  //std::cout << "begin config()" << std::endl;
967  //std::cout << " mat:\n" << mat << std::endl;
968 
969  const Structure &prim = (*primclex).get_prim();
970 
971  // create a 'superstruc' that fills '*this'
972  BasicStructure<Site> superstruc = structure_to_config.create_superstruc(real_super_lattice);
973 
974  //std::cout << "superstruc:\n";
975  //superstruc.print(std::cout);
976  //std::cout << " " << std::endl;
977 
978  // Set the occuation state of a Configuration from superstruc
979  // Allow Va on sites where Va are allowed
980  // Do not allow interstitials, print an error message and exit
981  Configuration config(*this);
982 
983  // Initially set occupation to -1 (for unknown) on every site
984  config.set_occupation(Array<int>(num_sites(), -1));
985 
986  Index linear_index, b;
987  int val;
988 
989  // For each site in superstruc, set occ index
990  for(Index i = 0; i < superstruc.basis.size(); i++) {
991  //std::cout << "i: " << i << " basis: " << superstruc.basis[i] << std::endl;
992  linear_index = get_linear_index(Coordinate(superstruc.basis[i]), tol);
993  b = get_b(linear_index);
994 
995  // check that we're not over-writing something already set
996  if(config.occ(linear_index) != -1) {
997  std::cerr << "Error in Supercell::config." << std::endl;
998  std::cerr << " Adding a second atom on site: linear index: " << linear_index << " bijk: " << uccoord(linear_index) << std::endl;
999  exit(1);
1000  }
1001 
1002  // check that the Molecule in superstruc is allowed on the site in 'prim'
1003  if(!prim.basis[b].contains(superstruc.basis[i].occ_name(), val)) {
1004  std::cerr << "Error in Supercell::config." << std::endl;
1005  std::cerr << " The molecule: " << superstruc.basis[i].occ_name() << " is not allowed on basis site " << b << " of the Supercell prim." << std::endl;
1006  exit(1);
1007  }
1008  config.set_occ(linear_index, val);
1009  }
1010 
1011  // Check that vacant sites are allowed
1012  for(Index i = 0; i < config.size(); i++) {
1013  if(config.occ(i) == -1) {
1014  b = get_b(i);
1015 
1016  if(prim.basis[b].contains("Va", val)) {
1017  config.set_occ(i, val);
1018  }
1019  else {
1020  std::cerr << "Error in Supercell::config." << std::endl;
1021  std::cerr << " Missing atom. Vacancies are not allowed on the site: " << uccoord(i) << std::endl;
1022  exit(1);
1023  }
1024  }
1025  }
1026 
1027  return config;
1028 
1029  };
1030 
1031  //***********************************************************
1036  //***********************************************************
1038  // create a 'superstruc' that fills '*this'
1039  Structure superstruc = (*primclex).get_prim().create_superstruc(real_super_lattice);
1040 
1041  Index linear_index;
1042  // sort basis sites so that they agree with config_index_to_bijk
1043  // This sorting may not be necessary,
1044  // but it depends on how we construct the config_index_to_bijk,
1045  // so I'll leave it in for now just to be safe
1046  for(Index i = 0; i < superstruc.basis.size(); i++) {
1047  linear_index = get_linear_index(superstruc.basis[i]);
1048  superstruc.basis.swap_elem(i, linear_index);
1049  }
1050 
1051  //superstruc.reset();
1052 
1053  //set_site_internals() is better than Structure::reset(), because
1054  //it doesn't destroy all the info that
1055  //Structure::create_superstruc makes efficiently
1056  superstruc.set_site_internals();
1057  return superstruc;
1058 
1059  }
1060 
1061  //***********************************************************
1067  //***********************************************************
1069  // create a 'superstruc' that fills '*this'
1070  Structure superstruc = superstructure();
1071 
1072  // set basis site occupants
1073  for(Index i = 0; i < superstruc.basis.size(); i++) {
1074  superstruc.basis[i].set_occ_value(config.occ(i));
1075  }
1076 
1077  // setting the occupation changes symmetry properties, so must reset
1078  superstruc.reset();
1079 
1080  return superstruc;
1081 
1082  }
1083 
1091  if(config_index >= config_list.size()) {
1092  std::cerr << "ERROR in Supercell::superstructure" << std::endl;
1093  std::cerr << "Requested superstructure of configuration with index " << config_index << " but there are only " << config_list.size() << " configurations" << std::endl;
1094  exit(185);
1095  }
1096  return superstructure(config_list[config_index]);
1097  }
1098 
1099  //***********************************************************
1104  //***********************************************************
1106  Array<int> occupation = Array<int>(num_sites(), -1);
1107  int b, index;
1108  for(Index i = 0; i < num_sites(); i++) {
1109  b = get_b(i);
1110  if(get_prim().basis[b].contains("Va", index)) {
1111  occupation[i] = index;
1112  }
1113  }
1114  return occupation;
1115  }
1116 
1117  //**********************************************************
1121  //**********************************************************
1123  Eigen::MatrixXd real_coords(volume(), 3);
1124  for(int i = 0; i < volume(); i++) {
1125  Coordinate temp_real_point = m_prim_grid.coord(i, SCEL);
1126  temp_real_point.within(); //should this also be voronoi within?
1127  real_coords.row(i) = temp_real_point.const_cart().transpose();
1128  }
1129  return real_coords;
1130  }
1131 
1132  //**********************************************************
1138  //**********************************************************
1140  Eigen::MatrixXd kpoint_coords(volume(), 3);
1141  Lattice temp_recip_lattice = (*primclex).get_prim().lattice().get_reciprocal();
1142  for(int i = 0; i < volume(); i++) {
1143  // std::cout<<"UCC:"<<recip_grid.uccoord(i);
1144  Coordinate temp_kpoint = recip_grid.coord(i, PRIM);
1145  temp_kpoint.set_lattice(temp_recip_lattice, CART);
1146  temp_kpoint.within(); //This is temporary, should be replaced by a call to voronoi_within()
1147 
1148  kpoint_coords.row(i) = temp_kpoint.const_cart().transpose();
1149  }
1150  return kpoint_coords;
1151  }
1152 
1154  Eigen::MatrixXd recip_frac_coords = recip_coordinates * recip_prim_lattice.inv_lat_column_mat();
1155  // std::cout<<"Recip Frac Coords"<<std::endl<<recip_frac_coords<<std::endl;
1156  Array<bool> is_commensurate(recip_coordinates.rows(), true);
1157  for(int i = 0; i < recip_frac_coords.rows(); i++) {
1158  for(int j = 0; j < recip_frac_coords.cols(); j++) {
1159  if(std::abs(round(recip_frac_coords(i, j)) - recip_frac_coords(i, j)) > tol) {
1160  is_commensurate[i] = false;
1161  break;
1162  }
1163  }
1164  }
1165  return is_commensurate;
1166  }
1167 
1170  }
1171 
1172  void Supercell::generate_fourier_matrix(const Eigen::MatrixXd &real_coordinates, const Eigen::MatrixXd &recip_coordinates) {
1173  generate_fourier_matrix(real_coordinates, recip_coordinates, false);
1174  }
1175 
1176  void Supercell::generate_fourier_matrix(const Eigen::MatrixXd &real_coordinates, const Eigen::MatrixXd &recip_coordinates, const bool &override) {
1177  //Validate the input matrices
1178  if((real_coordinates.cols() != 3) || recip_coordinates.cols() != 3) {
1179  std::cerr << "ERROR in generate_fourier_matrix, your matrices are incorrectly initialized" << std::endl;
1180  std::cerr << "QUITTING" << std::endl;
1181  exit(666);
1182  }
1183  //Check if m_k_mesh is already full
1184  if(m_k_mesh.rows() != 0 || m_k_mesh.cols() != 0) {
1185  std::cerr << "WARNING in Supercell::generate_fourier_matrix. You already have a k-mesh in this Supercell"
1186  << " It will be overwritten" << std::endl;
1187  }
1189  // Setup the size of _fourier_matrix which is only the -i*r*k'
1190  Eigen::MatrixXcd _fourier_matrix(real_coordinates.rows(), m_k_mesh.rows());
1191  std::complex<double> pre_factor(0, -1);
1192  _fourier_matrix = pre_factor * real_coordinates * m_k_mesh.transpose();
1193  //Exponentiate every element of _fourier matrix and store in m_fourier_matrix
1194  m_fourier_matrix = _fourier_matrix.array().exp();
1195  //Find all those k-point that are not commensurate with this supercell and
1196  // set those columns of the fourier_matrix to be zeros
1197  Array<bool> is_commensurate(recip_coordinates.rows(), true);
1198  if(!override) {
1199  is_commensurate = is_commensurate_kpoint(recip_coordinates);
1200  for(int i = 0; i < m_fourier_matrix.cols(); i++) {
1201  if(!is_commensurate[i]) {
1202  m_fourier_matrix.col(i) = Eigen::MatrixXcd::Zero(m_fourier_matrix.rows(), 1);
1203  }
1204  }
1205  }
1206  generate_phase_factor((*primclex).shift_vectors(), is_commensurate, override);
1207  // std::cout<<"Fourier Matrix:"<<std::endl<<m_fourier_matrix<<std::endl;
1208  }
1209 
1210  void Supercell::generate_phase_factor(const Eigen::MatrixXd &shift_vectors, const Array<bool> &is_commensurate, const bool &override) {
1211  Eigen::MatrixXcd _phase_factor(basis_size(), m_k_mesh.rows());
1212  std::complex<double> pre_factor(0, -1);
1213  // std::cout<<"Shift vectors"<<std::endl<<shift_vectors<<std::endl;
1214  _phase_factor = pre_factor * shift_vectors * m_k_mesh.transpose();
1215  m_phase_factor = _phase_factor.array().exp();
1216  //Zero out all the rows of m_phase_factor that have k-points that are
1217  //not commensurate with the Supercell
1218  if(!override) {
1219  for(int i = 0; i < m_phase_factor.cols(); i++) {
1220  if(!is_commensurate[i]) {
1221  m_phase_factor.col(i) = Eigen::MatrixXcd::Zero(m_phase_factor.rows(), 1);
1222  }
1223  }
1224  }
1225  //std::cout<<"Phase factors:"<<std::endl<<m_phase_factor<<std::endl;
1226  }
1227 
1229  if(m_fourier_matrix.rows() == 0 || m_fourier_matrix.cols() == 0 || m_phase_factor.rows() == 0 || m_phase_factor.cols() == 0) {
1231  }
1232  for(Index i = 0; i < config_list.size(); i++) {
1234  }
1235  return;
1236  }
1237 
1238  void Supercell::populate_structure_factor(const Index &config_index) {
1239  if(m_fourier_matrix.rows() == 0 || m_fourier_matrix.cols() == 0 || m_phase_factor.rows() == 0 || m_phase_factor.cols() == 0) {
1241  }
1242  config_list[config_index].calc_struct_fact();
1243  return;
1244  }
1245 
1246  bool Supercell::operator<(const Supercell &B) const {
1247  if(&get_primclex() != &B.get_primclex()) {
1248  throw std::runtime_error(
1249  "Error using Supercell::operator<(const Supercell& B): "
1250  "Only Supercell with the same PrimClex may be compared this way.");
1251  }
1252  if(volume() != B.volume()) {
1253  return volume() < B.volume();
1254  }
1256  }
1257 
1258  bool Supercell::_eq(const Supercell &B) const {
1259  if(&get_primclex() != &B.get_primclex()) {
1260  throw std::runtime_error(
1261  "Error using Supercell::operator==(const Supercell& B): "
1262  "Only Supercell with the same PrimClex may be compared this way.");
1263  }
1264  return get_transf_mat() == B.get_transf_mat();
1265  }
1266 
1267  Supercell &apply(const SymOp &op, Supercell &scel) {
1268  return scel = copy_apply(op, scel);
1269  }
1270 
1271  Supercell copy_apply(const SymOp &op, const Supercell &scel) {
1272  return Supercell(&scel.get_primclex(), copy_apply(op, scel.get_real_super_lattice()));
1273  }
1274 
1275 
1276  std::string generate_name(const Eigen::Matrix3i &transf_mat) {
1277  std::string name_str;
1278 
1279  Eigen::Matrix3i H = hermite_normal_form(transf_mat).first;
1280  name_str = "SCEL";
1281  std::stringstream tname;
1282  //Consider using a for loop with HermiteCounter_impl::_canonical_unroll here
1283  tname << H(0, 0)*H(1, 1)*H(2, 2) << "_" << H(0, 0) << "_" << H(1, 1) << "_" << H(2, 2) << "_" << H(1, 2) << "_" << H(0, 2) << "_" << H(0, 1);
1284  name_str.append(tname.str());
1285 
1286  return name_str;
1287  }
1288 
1289 }
const Configuration & get_config(Index i) const
Definition: Supercell.hh:287
const Array< Permutation > & translation_permute() const
Definition: Supercell.cc:154
Eigen::MatrixXd MatrixXd
Supercell(const Supercell &RHS)
Definition: Supercell.cc:694
SymOp from_canonical() const
Definition: Supercell.cc:902
Coordinate coord(const UnitCellCoord &bijk) const
Definition: Supercell.cc:45
void set_site_internals()
Associate each site with its basis index by setting its internal flags (asym_ind -> -1) ...
void _add_canon_config(const Configuration &config)
Definition: Supercell.cc:638
std::string get_name() const
Return supercell name.
Definition: Supercell.cc:123
ConfigIterator< const Configuration, const PrimClex > config_const_iterator
Definition: Supercell.hh:45
Eigen::MatrixXcd m_fourier_matrix
Definition: Supercell.hh:100
bool is_canonical(double tol=TOL) const
Check if Lattice is in the canonical form.
Definition: Lattice.cc:235
ReturnArray< int > max_allowed_occupation() const
Definition: Supercell.cc:61
void generate_factor_group() const
Definition: Supercell.cc:821
std::string m_name
unique name of the supercell based on hermite normal form (see _generate_name() ) ...
Definition: Supercell.hh:88
bool contains(const T &test_elem) const
Definition: Array.hh:281
PermuteIterator permute_const_iterator
Definition: Supercell.hh:48
std::map< const Configuration *, Index, ConfigMapCompare > m_config_map
Definition: Supercell.hh:149
std::pair< config_const_iterator, bool > insert_config(const Configuration &config)
Insert a configuration that may be non-canonical.
Definition: Supercell.cc:611
const int & occ(Index site_l) const
Occupant variable on site l.
Index size() const
Definition: Array.hh:145
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
Definition: Coordinate.hh:593
SymGroupRep const & permutation_symrep() const
Definition: Supercell.hh:255
void generate_point_group(SymGroup &point_group, double pg_tol=TOL) const
Populate.
Definition: Lattice.cc:304
bool empty() const
Returns true if SymGroupRepID has not been initialized with valid group_index or rep_index.
Eigen::Matrix3i transf_mat
Definition: Supercell.hh:151
std::string generate_name(const Eigen::Matrix3i &transf_mat)
Definition: Supercell.cc:1276
void push_back(const T &toPush)
Definition: Array.hh:513
const Structure & get_prim() const
Definition: Supercell.cc:74
fs::path get_path() const
Return casm project directory path.
Definition: PrimClex.cc:202
PrimGrid m_prim_grid
Definition: Supercell.hh:60
Structure specifies the lattice and atomic basis of a crystal.
Definition: Structure.hh:29
PrimClex * primclex
Definition: settings.cc:101
Object copy_apply(const Transform &f, Object obj, Args &&...args)
Configuration canonical_form() const
Returns the canonical form Configuration in the same Supercell.
Configuration configuration(const BasicStructure< Site > &structure_to_config, double tol=TOL)
Definition: Supercell.cc:955
SymGroupRepID permutation_symrep_ID() const
Definition: Supercell.hh:249
Unit Cell Coordinates.
void _generate_name() const
Definition: Supercell.cc:858
BasicStructure create_superstruc(const Lattice &scel_lat, double map_tol=TOL) const
Shortcut routine to create a supercell structure and fill it with sites.
const jsonParser & source() const
notstd::cloneable_ptr< SuperNeighborList > m_nlist
Definition: Supercell.hh:136
const Lattice & get_real_super_lattice() const
Definition: Supercell.hh:267
SymOp to_canonical() const
Definition: Supercell.cc:894
Supercell & canonical_form() const
Definition: Supercell.cc:910
void generate_permutations() const
Definition: Supercell.cc:829
Main CASM namespace.
Definition: complete.cpp:8
const Lattice & lattice() const
PrimGrid recip_grid
Definition: Supercell.hh:63
const double TOL
Supercell * m_canonical
Store a pointer to the canonical equivalent Supercell.
Definition: Supercell.hh:143
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:37
const vector_type & const_cart() const
user override to force const Access the Cartesian coordinate vector
Definition: Coordinate.hh:92
config_const_iterator config_cend() const
Definition: Supercell.cc:113
Lattice recip_prim_lattice
Definition: Supercell.hh:58
void generate_fourier_matrix()
Structure Factor.
Definition: Supercell.cc:1168
bool contains_config(const Configuration &config) const
Definition: Supercell.cc:522
PrimClex & get_primclex() const
Definition: Supercell.hh:201
Index basis_size() const
Definition: Supercell.hh:216
Index find(const Coordinate &_coord) const
Definition: PrimGrid.cc:144
void read_config_list(const jsonParser &json)
Definition: Supercell.cc:654
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
Definition: jsonParser.cc:185
jsonParser & write_config_list(jsonParser &json)
Call Configuration::write out every configuration in supercell.
Definition: Supercell.cc:758
fs::path get_path() const
Return path to supercell directory.
Definition: Supercell.cc:865
void reset()
clears symmetry, site internals, and other attributes
Definition: Structure.cc:385
The SuperNeighborList gives the linear indices of neighboring sites and unitcells in a particular Sup...
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:33
std::string get_id() const
double tol
void generate_phase_factor(const Eigen::MatrixXd &shift_vectors, const Array< bool > &is_commensurate, const bool &override)
Definition: Supercell.cc:1210
const Eigen::Matrix3d & inv_lat_column_mat() const
Inverse of Lattice::lat_column_mat() It is the transformation matrix 'C2F', such that f = C2F * c whe...
Definition: Lattice.hh:113
void clear()
Definition: Array.hh:216
permute_const_iterator permute_begin() const
Definition: Supercell.cc:179
double crystallography_tol() const
Definition: PrimClex.hh:124
Lattice real_super_lattice
Definition: Supercell.hh:55
void print_PERTURB_json(std::ofstream &file, const Configuration &background_config, const Array< Array< Array< Index > > > &perturb_config_index, const Array< Array< Array< permute_const_iterator > > > &perturb_config_symop_index, bool print_config_name) const
Definition: Supercell.cc:775
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
ConfigIterator< Configuration, PrimClex > config_iterator
Definition: Supercell.hh:44
SymGroupRepID make_permutation_representation(const SymGroup &group, SymGroupRepID basis_permute_rep) const
Definition: PrimGrid.cc:247
const SuperNeighborList & nlist() const
Returns the SuperNeighborList.
Definition: Supercell.cc:79
PrimClex * primclex
Definition: Supercell.hh:52
EigenIndex Index
For long integer indexing:
Index volume() const
Return number of primitive cells that fit inside of *this.
Definition: Supercell.hh:212
Array< bool > is_commensurate_kpoint(const Eigen::MatrixXd &recip_coordinates, double tol=TOL)
Definition: Supercell.cc:1153
void set_occupation(const Array< int > &newoccupation)
Set occupant variables.
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
bool add_canon_config(const Configuration &config, Index &index)
Definition: Supercell.cc:590
Structure superstructure() const
Definition: Supercell.cc:1037
Index m_id
index into PrimClex::supercell_list
Definition: Supercell.hh:156
bool add_config(const Configuration &config)
Definition: Supercell.cc:568
fs::path get_path() const
SymOp to_canonical(double tol=TOL) const
Returns the operation that applied to *this returns the canonical form.
Definition: Lattice.cc:249
permute_const_iterator translate_begin() const
Begin iterator over pure translational permutations.
Definition: Supercell.cc:161
const SymGroup & factor_group() const
Definition: Supercell.cc:132
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:52
UnitCellCoord uccoord(Index i) const
Definition: Supercell.hh:224
bool is_supercell_of(const Structure &structure) const
Definition: Supercell.cc:924
bool is_supercell_of(const Lattice &tile, Eigen::Matrix3d &multimat, double _tol=TOL) const
Matrix that relates two lattices (e.g., strain or slat)
Definition: Lattice.cc:655
Eigen::MatrixXd real_coordinates() const
Definition: Supercell.cc:1122
Structure create_superstruc(const Lattice &scel_lat, double map_tol=TOL) const
Shortcut routine to create a supercell structure and fill it with sites.
Definition: Structure.cc:335
void set_lattice(const Lattice &new_lat, COORD_TYPE mode)
Change the home lattice of the coordinate, selecting one representation (either CART or FRAC) that re...
Definition: Coordinate.cc:245
Index get_linear_index(const Site &site, double tol=TOL) const
Definition: Supercell.cc:18
config_const_iterator config_cbegin() const
Definition: Supercell.cc:109
std::string name() const
SCELV_A_B_C_D_E_F/i.
PermuteIterator begin_next_fg_op() const
PrimNeighborList & nlist() const
Access to the primitive neighbor list.
Definition: PrimClex.cc:266
void swap_elem(Index i, Index j)
Definition: Array.hh:231
virtual void read(std::istream &stream)
Print intpolated images in seperate directries.
Index find(const UnitCellCoord &bijk) const
Definition: Supercell.cc:39
Index size() const
Returns number of sites, NOT the number of primitives that fit in here.
std::pair< Eigen::MatrixXi, Eigen::MatrixXi > hermite_normal_form(const Eigen::MatrixXi &M)
Return the hermite normal form, M == H*V.
void enumerate_perturb_configurations(const std::string &background, fs::path CSPECS, double tol=TOL, bool verbose=false, bool print=false)
Definition: Supercell.cc:211
Array & append(const Array &new_tail)
Definition: Array.hh:897
SymOpOutputIterator find_invariant_subgroup(SymOpIterator begin, SymOpIterator end, SymOpOutputIterator result, double pg_tol=TOL) const
Output the SymOp that leave this lattice invariant.
Definition: Lattice_impl.hh:77
Index get_id() const
Definition: Supercell.hh:303
Eigen::Matrix3d Matrix3d
Eigen::MatrixXd m_k_mesh
Definition: Supercell.hh:127
PermuteIterator to_canonical() const
Returns the operation that applied to *this returns the canonical form.
Permutation const * get_permutation(Index i) const
Definition: SymGroupRep.cc:265
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
size_type size() const
size of the neighborhood of unit cells
Definition: NeighborList.cc:77
const ClustType & prototype(Index np, Index no) const
Access prototype of orbit (np, no)
Lattice get_reciprocal() const
Return reciprocal lattice.
Definition: Lattice.cc:149
bool is_canonical() const
Definition: Supercell.cc:886
const Supercell & get_supercell(Index i) const
const Access supercell by index
Definition: PrimClex.cc:311
Eigen::MatrixXd recip_coordinates() const
Definition: Supercell.cc:1139
config_iterator config_end()
Definition: Supercell.cc:104
void set_source(const jsonParser &source)
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
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
Definition: jsonParser.cc:500
config_iterator config_begin()
Definition: Supercell.cc:100
void set_occ(Index site_l, int val)
Set occupant variable on site l.
const Array< Permutation > & translation_permutations() const
const access to m_trans_permutations. Generates permutations if they don't already exist...
Definition: PrimGrid.hh:147
void set_lattice(const Lattice &new_lat)
Definition: SymGroup.cc:435
const Permutation & factor_group_permute(Index i) const
Definition: Supercell.cc:141
void populate_structure_factor()
Definition: Supercell.cc:1228
Eigen::MatrixXcd m_phase_factor
Definition: Supercell.hh:108
Index amount_selected() const
Count how many configs are selected in *this.
Definition: Supercell.cc:874
ConfigList config_list
Definition: Supercell.hh:146
void set_selected(bool _selected)
bool _eq(const Supercell &B) const
Definition: Supercell.cc:1258
Coordinate coord(Index l, CELL_TYPE lat_mode) const
Definition: PrimGrid.cc:223
std::pair< config_const_iterator, bool > insert_canon_config(const Configuration &config)
Insert a configuration that is known to be canonical.
Definition: Supercell.cc:619
bool operator<(const Supercell &B) const
Definition: Supercell.cc:1246
Supercell & get_supercell() const
Get the Supercell for this Configuration.
const Eigen::Matrix3i & get_transf_mat() const
Definition: Supercell.hh:263
Index get_b(Index i) const
Definition: Supercell.hh:259
Index m_nlist_size_at_construction
Definition: Supercell.hh:140
ReturnArray< int > vacant() const
Definition: Supercell.cc:1105
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value) ...
Definition: algorithm.hh:66
const Permutation & translation_permutation(Index i) const
Definition: PrimGrid.hh:159
SymGroupRepID m_perm_symrep_ID
Definition: Supercell.hh:72
static jsonParser object()
Returns an empty json object.
Definition: jsonParser.hh:329
permute_const_iterator permute_end() const
Definition: Supercell.cc:185
SymOp from_canonical(double tol=TOL) const
Returns the operation that applied to the canonical form returns *this.
Definition: Lattice.cc:273
static jsonParser array()
Returns an empty json array.
Definition: jsonParser.hh:342
Object & apply(const Transform &f, Object &obj, Args &&...args)
permute_const_iterator permute_it(Index fg_index, Index trans_index) const
Definition: Supercell.cc:191
Index size(Index np) const
Number of orbits in OrbitBranch 'np'.
SymGroup m_factor_group
Definition: Supercell.hh:85
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
void print_bijk(std::ostream &stream)
Definition: Supercell.cc:200
int round(double val)
Definition: CASM_math.cc:6