CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
Structure.cc
Go to the documentation of this file.
2 
3 #include <sstream>
4 #include <string>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 
11 #include "casm/misc/algorithm.hh"
12 
13 
14 namespace CASM {
15  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 
19  if(!fs::exists(filepath)) {
20  std::cerr << "Error in Structure::Structure(const fs::path &filepath)." << std::endl;
21  std::cerr << " File does not exist at: " << filepath << std::endl;
22  exit(1);
23  }
24  fs::ifstream infile(filepath);
25 
26  read(infile);
27  }
28 
29  //***********************************************************
30 
32  BasicStructure<Site>(RHS) {
33 
35 
36  };
37 
38  //***********************************************************
39 
42 
43  //Following gets done by base class
44  //lattice = RHS.lattice;
45  //basis = RHS.basis;
46  //title = RHS.title;
47 
48  /*
49  for(Index i = 0; i < basis.size(); i++) {
50  basis[i].set_lattice(lattice);
51  }
52  */
53 
55 
56  return *this;
57  }
58 
59 
60  //***********************************************************
61 
63 
65 
66  SD_flag = RHS.SD_flag;
67 
68  basis_perm_rep_ID = RHS.basis_perm_rep_ID; //this *should* work
69 
72  }
73 
74  //***********************************************************
75 
76 
77  void Structure::generate_factor_group_slow(double map_tol) const {
81  return;
82  }
83 
84  //************************************************************
85  void Structure::generate_factor_group(double map_tol) const {
88  //std::cout << "GENERATING STRUCTURE FACTOR GROUP " << &m_factor_group << "\n";
90  return;
91  }
92 
93  //************************************************************
95  if(!m_factor_group.size())
97  return m_factor_group;
98  }
99 
100  //************************************************************
102  return factor_group().point_group();
103  }
104 
105  //***********************************************************
106 
109  }
110 
111  //***********************************************************
112 
116 
117  return basis_perm_rep_ID;
118  }
119 
120  //************************************************************
121 
123  std::vector<Specie> Structure::get_struc_specie() const {
124 
125  std::vector<Molecule> struc_molecule = get_struc_molecule();
126  std::vector<Specie> struc_specie;
127 
128  Index i, j;
129 
130  //For each molecule type
131  for(i = 0; i < struc_molecule.size(); i++) {
132  // For each atomposition in the molecule
133  for(j = 0; j < struc_molecule[i].size(); j++) {
134  if(!contains(struc_specie, struc_molecule[i][j].specie)) {
135  struc_specie.push_back(struc_molecule[i][j].specie);
136  }
137  }
138  }
139 
140  return struc_specie;
141  }
142 
143  //************************************************************
144 
146  std::vector<Molecule> Structure::get_struc_molecule() const {
147 
148  std::vector<Molecule> struc_molecule;
149  Index i, j;
150 
151  //loop over all Sites in basis
152  for(i = 0; i < basis.size(); i++) {
153  //loop over all Molecules in Site
154  for(j = 0; j < basis[i].site_occupant().size(); j++) {
155  //Collect unique Molecules
156  if(!contains(struc_molecule, basis[i].site_occupant()[j])) {
157  struc_molecule.push_back(basis[i].site_occupant()[j]);
158  }
159  }
160  }//end loop over all Sites
161 
162  return struc_molecule;
163  }
164 
166  std::vector<std::string> Structure::get_struc_molecule_name() const {
167 
168  // get Molecule allowed in prim, and how many there are
169  std::vector<Molecule> struc_mol = get_struc_molecule();
170 
171  // store Molecule names in vector
172  std::vector<std::string> struc_mol_name;
173  for(int i = 0; i < struc_mol.size(); i++) {
174  struc_mol_name.push_back(struc_mol[i].name);
175  }
176 
177  return struc_mol_name;
178  }
179 
180  //************************************************************
181 
184  Eigen::VectorXi Structure::get_num_each_specie() const {
185 
186  std::vector<Specie> struc_specie = get_struc_specie();
187  Eigen::VectorXi num_each_specie = Eigen::VectorXi::Zero(struc_specie.size());
188 
189  Index i, j;
190  // For each site
191  for(i = 0; i < basis.size(); i++) {
192  // For each atomposition in the molecule on the site
193  for(j = 0; j < basis[i].occ().size(); j++) {
194  // Count the present specie
195  num_each_specie(find_index(struc_specie, basis[i].occ()[j].specie))++;
196  }
197  }
198 
199  return num_each_specie;
200  }
201 
202  //************************************************************
203 
206  Eigen::VectorXi Structure::get_num_each_molecule() const {
207 
208  std::vector<Molecule> struc_molecule = get_struc_molecule();
209  Eigen::VectorXi num_each_molecule = Eigen::VectorXi(struc_molecule.size());
210 
211  Index i;
212  // For each site
213  for(i = 0; i < basis.size(); i++) {
214  // Count the molecule
215  num_each_molecule(find_index(struc_molecule, basis[i].occ()))++;
216  }
217 
218  return num_each_molecule;
219  }
220 
221 
222 
223 
224  //************************************************************
225  void Structure::fg_converge(double small_tol, double large_tol, double increment) {
226  BasicStructure<Site>::fg_converge(m_factor_group, small_tol, large_tol, increment);
227  return;
228  }
229 
230  //************************************************************
231  void Structure::fg_converge(double large_tol) {
232  BasicStructure<Site>::fg_converge(m_factor_group, TOL, large_tol, (large_tol - TOL) / 10.0);
233  return;
234  }
235 
236  //************************************************************
237  /*void Structure::print_factor_group(std::ostream &stream) const {
238  stream << "Factor Group of " << title << ", containing "
239  << factor_group().size() << " symmetry operations:\n";
240 
241  for(Index i = 0; i < m_factor_group.size(); i++) {
242  m_factor_group[i].print(stream);
243  }
244 
245  return;
246  }
247  */
248  //***********************************************************
261  //***********************************************************
262 
263  void Structure::fill_supercell(const Structure &prim, double map_tol) {
264  Index i, j;
265 
266  SymGroup latvec_pg;
267  m_lattice.generate_point_group(latvec_pg);
268 
269  SD_flag = prim.SD_flag;
270  PrimGrid prim_grid(prim.lattice(), lattice());
271 
272  basis.clear();
273  Coordinate tcoord(lattice());
274 
275  //loop over basis sites of prim
276  for(j = 0; j < prim.basis.size(); j++) {
277 
278  //loop over prim_grid points
279  for(i = 0; i < prim_grid.size(); i++) {
280 
281  //push back translated basis site of prim onto superstructure basis
282  basis.push_back(prim.basis[j] + prim_grid.coord(i, PRIM));
283 
284  //reset lattice for most recent superstructure Site
285  //set_lattice() converts fractional coordinates to be compatible with new lattice
287 
288  basis.back().within();
289  for(Index k = 0; k < basis.size() - 1; k++) {
290  if(basis[k].compare(basis.back(), map_tol)) {
291  basis.pop_back();
292  break;
293  }
294  }
295  }
296  }
297  //std::cout << "WORKING ON FACTOR GROUP " << &m_factor_group << " for structure with volume " << prim_grid.size() << ":\n";
298  //trans_and_expand primitive factor_group
299  for(i = 0; i < prim.factor_group().size(); i++) {
300  if(latvec_pg.find_no_trans(prim.factor_group()[i]) == latvec_pg.size()) {
301  continue;
302  }
303  else {
304  for(Index j = 0; j < prim_grid.size(); j++) {
305  Coordinate t_tau(prim.factor_group()[i].tau() + prim_grid.coord(j, SCEL).const_cart(), lattice(), CART);
306  t_tau.within();
307  m_factor_group.push_back(SymOp(prim.factor_group()[i].matrix(),
308  t_tau.cart()));
309  }
310  }
311  }
312  if(m_factor_group.size() > 200) {// how big is too big? this is at least big enough for FCC conventional cell
313 #ifndef NDEBUG
314  std::cerr << "WARNING: You have a very large factor group of a non-primitive structure. Certain symmetry features will be unavailable.\n";
315 #endif
317  }
318  //std::cout << "Final size is: " << m_factor_group.size() << "\n";
319  update();
320 
321  return;
322  }
323 
324  //***********************************************************
333  //***********************************************************
334 
335  Structure Structure::create_superstruc(const Lattice &scel_lat, double map_tol) const {
336  Structure tsuper(scel_lat);
337  tsuper.fill_supercell(*this);
338  return tsuper;
339  }
340 
341  //***********************************************************
342  /*shorttag allows the user to decide whether or not to print the
343  * entire symmetry matrix. If shorttag=0, then only the name of the
344  * operation and the eigenvector will be printed. If it equals anything else,
345  * then the symmetry operation matrix will be printed out.
346  */
347 
348  void Structure::print_site_symmetry(std::ostream &stream, COORD_TYPE mode, int shorttag = 1, double tol = TOL) {
351 
352  stream << " Printing symmetry operations that leave each site unchanged:\n \n";
353  for(Index i = 0; i < asym_unit.size(); i++) {
354  for(Index j = 0; j < asym_unit[i].size(); j++) {
355  stream << "Site: ";
356  asym_unit.at(i).at(j).at(0).print(stream); //Print the site (not cluster) for the asymmetric unit
357  stream << " Total Symmetry Operations: " << asym_unit[i][j].clust_group().size() << "\n";
358 
359  for(Index nc = 0; nc < asym_unit[i][j].clust_group().size(); nc++) {
360  //print_short is a new fxn I added in SymOp to not print out the whole symmetry matrix
361  if(shorttag == 0) {
362  stream << std::setw(4) << nc + 1 << ": ";
363  //asym_unit[i][j].clust_group()[nc].print_short(stream); // I turned this off because the "print_short" function does not appear to exist...
364  }
365 
366 
367  else {
368  stream.flags(std::ios::left);
369  stream << "\n" << std::setw(3) << nc + 1 << ": ";
370  stream.unsetf(std::ios::left);
371  if(mode == CART)
372  asym_unit[i][j].clust_group()[nc].print(stream, Eigen::Matrix3d::Identity());
373  else
374  asym_unit[i][j].clust_group()[nc].print(stream, lattice().inv_lat_column_mat());
375  }
376  }
377  stream << "\n --------------------------------------------------------------------- \n\n";
378  }
379  }
380  return;
381  }
382 
383  //***********************************************************
384 
386  //std::cout << "begin reset() " << this << std::endl;
387 
388  for(Index nb = 0; nb < basis.size(); nb++) {
389  basis[nb].set_basis_ind(nb);
390  }
391  within();
393 
399  //std::cout << "finish reset()" << std::endl;
400  return;
401  }
402 
403  //***********************************************************
409  //***********************************************************
410  void Structure::generate_flowertrees(const SiteOrbitree &in_tree, Array<SiteOrbitree> &out_trees, double tol) {
411  if(out_trees.size() != 0) {
412  std::cerr << "WARNING in Structure::generate_flowertrees_safe" << std::endl;
413  std::cerr << "The provided array of SiteOrbitree wasn't empty! Hope nothing important was there..." << std::endl;
414  out_trees.clear();
415  }
416 
417 
418  //Theres a flowertree for each basis site b
419  for(Index b = 0; b < basis.size(); b++) {
420  SiteOrbitree ttree(lattice(), tol); //Weird behavior without this
421  ttree.reserve(in_tree.size());
422  out_trees.push_back(ttree);
423  //We want clusters of every size in the tree, except the 0th term (...right guys?)
424  for(Index s = 1; s < in_tree.size(); s++) {
425  //Make each site basis into a cluster so we can use extract_orbits_including
426  SiteCluster tsiteclust(lattice());
427  tsiteclust.within();
428  tsiteclust.push_back(basis[b]);
429  //Make a branch where all the clusters of a given size s go
430  SiteOrbitBranch tbranch(lattice());
431  //Push back flower onto tree
432  out_trees[b].push_back(tbranch);
433  //Get one flower for a given basis site
434  in_tree[s].extract_orbits_including(tsiteclust, out_trees[b].back(), tol); //couldn't get it to work withough directly passing tree.back() (i.e. can't make branch then push_back)
435  }
436  out_trees[b].get_index();
437  out_trees[b].collect_basis_info(*this);
438  }
439 
440  return;
441  }
442 
443  //***********************************************************
444  // Fills an orbitree such that each OrbitBranch corresponds to a basis site and contains all orbits
445  // that include that basis site
446  void Structure::generate_basis_bouquet(const SiteOrbitree &in_tree, SiteOrbitree &out_tree, Index num_sites, double tol) {
447  Index na, np, nb, ne;
448 
449  out_tree.clear(); //Added by Ivy 11/07/12
450 
451  //make room in out_tree for flowers
452  //out_tree.reserve(basis.size());
453 
454  out_tree.lattice = in_tree.lattice;
455  //out_tree.set_lattice(in_tree.lattice,FRAC); //better?
456 
457  //get asymmetric unit
459  asym_unit.generate_asymmetric_unit(basis, factor_group(), tol);
460 
461 
462  for(na = 0; na < asym_unit.size(); na++) {
463  asym_unit.prototype(na).clust_group().character_table();
464  //std::cout << "Working on asym_unit element " << na + 1 << '\n';
465  nb = out_tree.size();
466 
467  //Add new branch with asym_unit.prototype(na) as pivot
468  out_tree.push_back(SiteOrbitBranch(asym_unit.prototype(na)));
469 
470  for(np = 0; np < in_tree.size(); np++) {
471  if(num_sites != in_tree[np].num_sites()) {
472  continue;
473  }
474  //std::cout << "Starting to extract petals from OrbitBranch " << np << '\n';
475  in_tree[np].extract_orbits_including(asym_unit.prototype(na), out_tree.back(), tol);
476  }
477 
478 
479  for(ne = 1; ne < asym_unit[na].equivalence_map.size(); ne++) {
480  out_tree.push_back(out_tree[nb]);
481  out_tree.back().apply_sym(asym_unit[na].equivalence_map[ne][0]);
482  }
483  }
484  //out_tree.get_index(); //Should not get_index because we want to keep the in_tree indices Ivy 01/15/14
485  out_tree.collect_basis_info(*this);
486  return;
487  }
488 
489  //***********************************************************
499  //***********************************************************
500  // Added by Ivy 10/17/12
501  void Structure::generate_asym_bouquet(const SiteOrbitree &in_tree, SiteOrbitree &out_tree, Index num_sites, double tol) {
502  Index na, np;//, nb;
503 
504  out_tree.clear();
505 
506  //get asymmetric unit
508  asym_unit.generate_asymmetric_unit(basis, factor_group(), tol);
509 
510  //make room in out_tree for flowers
511  out_tree.reserve(asym_unit.size());
512 
513  out_tree.lattice = in_tree.lattice;
514 
515 
516  for(na = 0; na < asym_unit.size(); na++) {
517 
518  //nb = out_tree.size();
519 
520  //Add new branch with asym_unit.prototype(na) as pivot
521  out_tree.push_back(SiteOrbitBranch(asym_unit.prototype(na)));
522 
523  for(np = 0; np < in_tree.size(); np++) {
524  if(num_sites != in_tree[np].num_sites()) {
525  continue;
526  }
527 
528  //prototype of na orbit
529  in_tree[np].extract_orbits_including(asym_unit.prototype(na), out_tree.back(), tol);
530  }
531 
532  }
533  //out_tree.get_index(); //Should not get_index because we want to keep the in_tree indices Ivy 01/15/14
534  out_tree.collect_basis_info(*this);
535  return;
536 
537 
538  }
539 
540  //John G 230913
541 
542  //***********************************************************
561  //***********************************************************
562  void Structure::generate_flowertrees_safe(const SiteOrbitree &in_tree, Array<SiteOrbitree> &out_trees, double tol) { //can we make it const? It would require generate_basis_bouquet to also be const
563  if(out_trees.size() != 0) {
564  std::cerr << "WARNING in Structure::generate_flowertrees_safe" << std::endl;
565  std::cerr << "The provided array of SiteOrbitree wasn't empty! Hope nothing important was there..." << std::endl;
566  out_trees.clear();
567  }
568 
569  //Determine what the largest cluster in the given orbitree is, accounting for the fact that there's a 0 point cluster
570  Index max_clust_size = in_tree.size() - 1;
571  //Plant all the bouquets, one for each cluster size and store them in
572  Array<SiteOrbitree> bouquets;
573 
574  for(Index i = 1; i < (max_clust_size + 1); i++) {
575  SiteOrbitree tbouquet(lattice(), tol);
576  generate_basis_bouquet(in_tree, tbouquet, i, tol);
577  bouquets.push_back(tbouquet);
578  }
579 
580  //Pluck a branch off each bouquet for a given basis site and stuff it into a SiteOribitree (this is a flowertree)
581  //SiteOrbitree tbouquet=in_tree; //This is so I don't have to worry about initializing things I'm scared of
582  SiteOrbitree tbouquet(lattice(), tol);
583 
584  //How many flowertrees do we need? As many as there are basis sites, i.e. bouquet[i].size();
585  for(Index i = 0; i < basis.size(); i++) {
586  tbouquet.clear();
587  //How many trees, i.e. cluster sizes
588  for(Index j = 0; j < bouquets.size(); j++) {
589  //Not pushing back empty cluster!!
590  tbouquet.push_back(bouquets[j][i]);
591  }
592  tbouquet.get_index();
593  tbouquet.collect_basis_info(*this);
594  out_trees.push_back(tbouquet);
595  }
596 
597  return;
598  }
599 
600  //\John G 230913
601 
602 
603  //*********************************************************
604 
606 
607  Index prim_to_scel;
608  Site shifted_site(prim.lattice());
609 
610 
611  //Check that (*this) is actually a supercell of the prim
612  if(!lattice().is_supercell_of(prim.lattice(), prim.point_group())) {
613  std::cerr << "*******************************************\n"
614  << "ERROR in Structure::map_superstruc_to_prim:\n"
615  << "The structure \n";
616  std::cerr << jsonParser(*this) << std::endl;
617  std::cerr << "is not a supercell of the given prim!\n";
618  std::cerr << jsonParser(prim) << std::endl;
619  std::cerr << "*******************************************\n";
620  exit(1);
621  }
622 
623  //Get prim grid of supercell to get the lattice translations
624  //necessary to stamp the prim in the superstructure
625  PrimGrid prim_grid(prim.lattice(), lattice());
626 
627  // Translate each of the prim atoms by prim_grid translation
628  // vectors, and map that translated atom in the supercell.
629  for(Index pg = 0; pg < prim_grid.size(); pg++) {
630  for(Index pb = 0; pb < prim.basis.size(); pb++) {
631  shifted_site = prim.basis[pb];
632  shifted_site += prim_grid.coord(pg, PRIM);
633  shifted_site.set_lattice(lattice(), CART);
634  shifted_site.within();
635 
636  // invalidate asym_ind and basis_ind because when we use
637  // Structure::find, we don't want a comparison using the
638  // basis_ind and asym_ind; we want a comparison using the
639  // cartesian and Specie type.
640 
641  shifted_site.set_basis_ind(-1);
642  prim_to_scel = find(shifted_site);
643 
644  if(prim_to_scel == basis.size()) {
645  std::cerr << "*******************************************\n"
646  << "ERROR in Structure::map_superstruc_to_prim:\n"
647  << "Cannot associate site \n"
648  << shifted_site << "\n"
649  << "with a site in the supercell basis. \n"
650  << "*******************************************\n";
651  std::cerr << "The basis_ind is "
652  << shifted_site.basis_ind() << "\n ";
653  exit(2);
654  }
655 
656  // Set ind_to_prim of the basis site
657  //basis[prim_to_scel].ind_to_prim = pb;
658  }
659  }
660  };
661 
662  //***********************************************************
663  //
664  void Structure::set_lattice(const Lattice &new_lat, COORD_TYPE mode) {
665  bool is_equiv(lattice() == new_lat);
666 
667  m_lattice = new_lat;
668 
669  for(Index nb = 0; nb < basis.size(); nb++) {
670  basis[nb].set_lattice(lattice(), mode);
671  }
672 
673  if(is_equiv)
675  else
676  reset();
677  }
678 
679 
680  //***********************************************************
690  //***********************************************************
691 
692  Structure Structure::stack_on(const Structure &understruc, bool override) const {
693  Structure overstruc(*this);
694 
695  //Before doing anything check to see that lattices are aligned correctly (paralled ab planes)
696  if(!override) {
697  double axbangle = angle(understruc.lattice()[0].cross(understruc.lattice()[1]), overstruc.lattice()[0].cross(overstruc.lattice()[1]));
698 
699  if(!almost_zero(axbangle)) {
700  std::cerr << "ERROR in Structure::stack_on" << std::endl;
701  std::cerr << "Lattice mismatch! Your structures are oriented differently in space. ab planes of structures must be parallel before stacking.\
702  Redefine your structure or use Structure::align_with to fix issue." << std::endl;
703  std::cerr << "Your vectors were:\n" << understruc.lattice()[0].cross(understruc.lattice()[1]) << "\n" << overstruc.lattice()[0].cross(overstruc.lattice()[1]) << std::endl;
704  exit(13);
705  }
706 
707  //Also check if c axes are on the same side of abplane
708  //else if
709  //{
710  //}
711  }
712 
713  else {
714  std::cerr << "WARNING in Structure::stack_on" << std::endl;
715  std::cerr << "You've chosen to ignore if ab planes of your structures are not parallel and/or c axes point the right way.\
716  This will almost surely result in a malformed structure. Do not take the output for granted." << std::endl;
717  }
718 
719 
720  //First stretch a and b of overstruc to match a and b of understruc
721  Lattice newoverstruclat(understruc.lattice()[0],
722  understruc.lattice()[1],
723  overstruc.lattice()[2]);
724 
725  overstruc.set_lattice(newoverstruclat, FRAC);
726 
727 
728  //Create a lattice big enough to fit both structures
729  Lattice heterolat(understruc.lattice()[0], //=overstruc.lattice()[0]
730  understruc.lattice()[1], //=overstruc.lattice()[1]
731  understruc.lattice()[2] + overstruc.lattice()[2]);
732 
733 
734  //Copy understruc and set its lattice to heterolat, keeping its cartesian coordinates.
735  //This leaves the basis intact but adds extra space where the overstruc basis can be placed.
736  Structure heterostruc(understruc);
737 
738  heterostruc.set_lattice(heterolat, CART);
739 
740  //Fill up empty space in heterostruc with overstruc
741  for(Index i = 0; i < overstruc.basis.size(); i++) {
742  Site tsite(overstruc.basis[i]);
743  tsite.cart() = tsite.const_cart() + understruc.lattice()[2];
744  tsite.set_lattice(heterostruc.lattice(), CART);
745  heterostruc.basis.push_back(tsite);
746 
747  }
748 
749  for(Index i = 0; i < heterostruc.basis.size(); i++) {
750  heterostruc.basis[i].within();
751  }
752 
753  heterostruc.update();
754 
755  return heterostruc;
756  }
757  //\John G 051112
758 
759  //John G 121212
760  //***********************************************************
768  //***********************************************************
770 
771  Structure reflectstruc(*this);
772  Eigen::Vector3d zreflect;
773  zreflect << 1, 1, -1;
774 
775  // resets the lattice and reflects cartesian coordinates of the basis atoms
776  reflectstruc.set_lattice(Lattice(zreflect.asDiagonal() * lattice().lat_column_mat()), FRAC);
777 
778  reflectstruc.update();
779 
780  return reflectstruc;
781  }
782 
783  //***********************************************************
792  //***********************************************************
793  void Structure::clump_atoms(double mindist, double tol) {
794 
795  // Warning, I don't think we want to do this here, but I'm leaving it in for now - JCT 03/07/14
796  update();
797 
798  //Define Orbitree just for pairs
799  SiteOrbitree siamese(lattice(), tol);
800  siamese.max_num_sites = 2;
801  siamese.max_length.push_back(0);
802  siamese.max_length.push_back(0);
803  siamese.max_length.push_back(mindist);
804  siamese.min_length = 0.0;
805  siamese.min_num_components = 1;
806  siamese.generate_orbitree(*this);
807 
808  //Set one atom of the cluster pairs to be at the average distance and flag
809  //the other one for removal later
810  for(Index i = 0; i < siamese[2].size(); i++) {
811  for(Index j = 0; j < siamese[2][i].size(); j++) {
812  Site avgsite(siamese[2][i][j][1]);
813  avgsite.cart() = (siamese[2][i][j][0].const_cart() + siamese[2][i][j][1].const_cart()) * 0.5;
814  avgsite.set_lattice(lattice(), CART); //It's dumb that I need to do this
815  avgsite.within();
816 
817  std::cout << "###############" << std::endl;
818  std::cout << siamese[2][i][j][0].basis_ind() << " " << siamese[2][i][j][0] << std::endl;
819  std::cout << siamese[2][i][j][1].basis_ind() << " " << siamese[2][i][j][1] << std::endl;
820  std::cout << "-------" << std::endl;
821  std::cout << basis[siamese[2][i][j][0].basis_ind()].basis_ind() << " " << basis[siamese[2][i][j][0].basis_ind()] << std::endl;
822  std::cout << basis[siamese[2][i][j][1].basis_ind()].basis_ind() << " " << basis[siamese[2][i][j][1].basis_ind()] << std::endl;
823  std::cout << "###############" << std::endl;
824 
825 
826  basis[siamese[2][i][j][0].basis_ind()].set_basis_ind(-99);
827  basis[siamese[2][i][j][1].basis_ind()].set_basis_ind(-99);
828  basis.push_back(avgsite);
829  }
830  }
831 
832  std::cout << "BASIS IND:" << std::endl;
833  //Remove unwanted atoms.
834  int bsize = basis.size();
835  for(int i = bsize - 1; i >= 0; i--) {
836  std::cout << basis[i].basis_ind() << " " << basis[i] << std::endl;
837  if(basis[i].basis_ind() == Index(-99)) {
838  basis.remove(i);
839  }
840  }
841 
842  update();
843 
844  return;
845  }
846 
847  //***********************************************************
856  //***********************************************************
857 
859 
860  for(Index i = 0; i < basis.size(); i++) {
861  for(Index j = 0; j < basis.size() - 1; j++) {
862 
863  if(basis[j].occ_name() > basis[j + 1].occ_name()) {
864  basis.swap_elem(j, j + 1);
865  }
866  }
867  }
868 
869  return;
870  }
871 
872 
873 
874  //John G 050513
875 
876  //***********************************************************
886  //***********************************************************
887 
888  Structure Structure::stamp_with(SiteCluster stamp, bool lat_override, bool im_override) const {
889  //The following check may not work properly
890  if(!lat_override && !lattice().is_supercell_of((stamp.home()), point_group())) {
891  std::cerr << "ERROR in Structure::stamp_with (are you using Structure::bedazzle?)" << std::endl;
892  std::cerr << "The lattice of your cluster is not related to the lattice of the structure you want to stamp!" << std::endl;
893  exit(60);
894  }
895 
896  //Some sort of check should happen here to make sure your superstructure
897  //is large enough to accomodate the stamp. Otherwise shit will get messed up
898  //I think image_check is the way to go, but I'm not sure I'm using it correctly
899  //I'm using the default value for nV (1) in image_check. This will allow the cluster
900  //to touch the faces of the voronoi cell.
901 
902  if(!im_override && stamp.size() > 1 && stamp.image_check(lattice(), 1)) { //Skip point clusters?
903  std::cerr << "ERROR in Structure::stamp_with" << std::endl;
904  std::cerr << "Your superstructure isn't big enough to fit your cluster!" << std::endl;
905  std::cerr << "Culprit:" << std::endl;
906  stamp.print(std::cerr);
907  exit(62);
908  }
909 
910  stamp.set_lattice(lattice(), CART);
911  stamp.within();
912 
913  Structure stampedstruc = *this;
914  Index sanity_count = 0;
915  for(Index i = 0; i < stamp.size(); i++) {
916  for(Index j = 0; j < basis.size(); j++) {
917  if(Coordinate(stamp[i]) == Coordinate(basis[j])) {
918  sanity_count++;
919  stampedstruc.basis[j] = stamp[i];
920  }
921  }
922  }
923 
924  if(sanity_count != stamp.size()) { //Allow if override?
925  std::cerr << "ERROR in Structure::stamp_with (are you using Structure::bedazzle?)" << std::endl;
926  std::cerr << stamp.size() - sanity_count << " sites in the cluster (size " << stamp.size() << " did not map onto your structure.\
927  If you got this far your lattices passed the test, but it seems your bases are unrelated. My guesses:" << std::endl;
928  std::cerr << "You're trying to map a relaxed site onto an ideal one." << std::endl;
929  std::cerr << "You have a vacancy in the structure you're stamping that's not in the basis." << std::endl;
930  exit(61);
931  }
932 
933  stampedstruc.reset();
934  return stampedstruc;
935  }
936 
937  //***********************************************************
943  //***********************************************************
944 
945  Array<Structure> Structure::bedazzle(Array<SiteCluster> stamps, bool lat_override, bool im_override) const {
946  Array<Structure> all_decorations;
947  for(Index i = 0; i < stamps.size(); i++) {
948  all_decorations.push_back(stamp_with(stamps[i], lat_override, im_override));
949  }
950 
951  return all_decorations;
952  }
953 
954  //***********************************************************
963  //***********************************************************
964 
965  Array<Array<Array<double> > > Structure::get_NN_table(const double &maxr, SiteOrbitree &bouquet, double tol) {
966  if(!bouquet.size()) {
967  std::cerr << "WARNING in Structure::get_NN_table" << std::endl;
968  std::cerr << "The provided SiteOrbitree is about to be rewritten!" << std::endl;
969  }
970 
972  SiteOrbitree normtree(lattice(), tol);
973  SiteOrbitree tbouquet(lattice(), tol);
974  bouquet = tbouquet;
975  normtree.min_num_components = 1;
976  normtree.max_num_sites = 2;
977  normtree.max_length.push_back(0.0);
978  normtree.max_length.push_back(0.0);
979  normtree.max_length.push_back(maxr);
980 
981  normtree.generate_orbitree(*this);
982  normtree.print_full_clust(std::cout);
983  generate_basis_bouquet(normtree, bouquet, 2, tol);
984 
985  Array<Array<double> > oneNN;
986  oneNN.resize(2);
987  for(Index i = 0; i < bouquet.size(); i++) {
988  NN.push_back(oneNN);
989  for(Index j = 0; j < bouquet[i].size(); j++) {
990  NN[i][0].push_back(bouquet[i][j].size());
991  NN[i][1].push_back(bouquet[i][j].max_length());
992  }
993  }
994 
995  return NN;
996  }
997 
998  //***********************************************************
1006  //***********************************************************
1007 
1008  Array<Array<Array<double> > > Structure::get_NN_table(const double &maxr, double tol) {
1009  SiteOrbitree bouquet(lattice(), tol);
1010  return get_NN_table(maxr, bouquet, tol);
1011  }
1012 
1013  //***********************************************************
1020  //***********************************************************
1021 
1022  void Structure::symmetrize(const SymGroup &relaxed_factors) {
1023  //First make a copy of your current basis
1024  //This copy will eventually become the new average basis.
1025  reset();
1026  Array<Site> avg_basis = basis;
1027 
1028  //Loop through given symmetry group an fill a temporary "operated basis"
1029  Array<Site> operbasis;
1030  for(Index rf = 0; rf < relaxed_factors.size(); rf++) {
1031  operbasis.clear();
1032  for(Index b = 0; b < basis.size(); b++) {
1033  operbasis.push_back(relaxed_factors[rf]*basis[b]);
1034  operbasis.back().print(std::cout);
1035  std::cout << std::endl;
1036  }
1037  //Now that you have a transformed basis, find the closest mapping of atoms
1038  //Then average the distance and add it to the average basis
1039  for(Index b = 0; b < basis.size(); b++) {
1040  double smallest = 1000000;
1041  Coordinate bshift(lattice()), tshift(lattice());
1042  for(Index ob = 0; ob < operbasis.size(); ob++) {
1043  double dist = operbasis[ob].min_dist(basis[b], tshift);
1044  if(dist < smallest) {
1045  bshift = tshift;
1046  smallest = dist;
1047  }
1048  }
1049  bshift.cart() *= (1.0 / relaxed_factors.size());
1050  avg_basis[b] += bshift;
1051  }
1052 
1053  }
1054  //generate_factor_group();
1055  update();
1056  return;
1057  }
1058 
1059  //***********************************************************
1067  //***********************************************************
1068 
1069  void Structure::symmetrize(const double &tolerance) {
1070  generate_factor_group(tolerance);
1072  return;
1073  }
1074 
1075  //\John G 050513
1076 
1077  //***********************************************************
1086  //***********************************************************
1087 
1088  void Structure::add_vacuum_shift(Structure &new_surface_struc, double vacuum_thickness, Eigen::Vector3d shift, COORD_TYPE mode) const {
1089 
1090  Coordinate cshift(shift, lattice(), mode); //John G 121030
1091  if(!almost_zero(cshift.frac(2))) {
1092  std::cerr << cshift.const_frac() << std::endl;
1093  std::cerr << "WARNING: You're shifting in the c direction! This will mess with your vacuum and/or structure!!" << std::endl;
1094  std::cerr << "See Structure::add_vacuum_shift" << std::endl;
1095  }
1096 
1097  Eigen::Vector3d vacuum_vec; //unit vector perpendicular to ab plane
1098  vacuum_vec = lattice()[0].cross(lattice()[1]);
1099  vacuum_vec.normalize();
1100  Lattice new_lattice(lattice()[0],
1101  lattice()[1],
1102  lattice()[2] + vacuum_thickness * vacuum_vec + cshift.const_cart()); //Add vacuum and shift to c vector
1103 
1104  new_surface_struc = *this;
1105  new_surface_struc.set_lattice(new_lattice, CART);
1106  return;
1107  }
1108 
1109  //***********************************************************
1110  void Structure::add_vacuum_shift(Structure &new_surface_struc, double vacuum_thickness, Coordinate shift) const {
1111 
1112  add_vacuum_shift(new_surface_struc, vacuum_thickness, shift.cart(), CART);
1113  return;
1114  }
1115 
1116  //***********************************************************
1117  void Structure::add_vacuum(Structure &new_surface_struc, double vacuum_thickness) const {
1118  Eigen::Vector3d shift(0, 0, 0);
1119 
1120  add_vacuum_shift(new_surface_struc, vacuum_thickness, shift, FRAC);
1121 
1122  return;
1123  }
1124 
1125  // Added by Donghee
1126 
1127  //***********************************************************
1137  //***********************************************************
1138 
1139  void Structure::intpol(Structure end_struc, int Nofimag, PERIODICITY_TYPE mode, Array<Structure> &images) {
1140 
1141  for(int m = 0; m < Nofimag + 1; m++) {
1142 
1143  Structure tstruc(end_struc);
1144 
1145  // Change title
1146  std::string header = "POSCAR 0";
1147  std::stringstream convert; // stringstream used for the conversion;
1148  convert << m;
1149  tstruc.title = header + convert.str(); // title of submiges is POSCAR0X
1150 
1151 
1152  for(Index i = 0 ; i < basis.size(); i++) {
1153  Coordinate temp(lattice());
1154 
1155  temp.frac() = (basis[i] - end_struc.basis[i]).const_frac() * m / (Nofimag + 1);
1156 
1157  tstruc.basis[i] = basis[i] + temp;
1158 
1159  }
1160 
1161  images.push_back(tstruc);
1162 
1163  }
1164  images.push_back(end_struc);
1165 
1166  return ;
1167  }
1168 
1169 
1170 
1171  //***********************************************************
1172 
1173  //This function gets the basis_permutation representation of the
1174  // factor group operations of the structure. It first applies
1175  // the factor group operation to the structure, and then tries
1176  // to map the new position of the basis atom to the various positions
1177  // before symmetry was applied. It only checks the positions after
1178  // it brings the basis within the crystal.
1179 
1180  // ROUTINE STILL NEEDS TO BE TESTED!
1181 
1184  return basis_perm_rep_ID;
1185  }
1186 
1187  //***********************************************************
1188 
1189  //Sets the occupants in the basis sites to those specified by occ_index
1191  if(occ_index.size() != basis.size()) {
1192  std::cerr << "The size of the occ index and basis index do not match!\nEXITING\n";
1193  exit(1);
1194  }
1195  for(Index i = 0; i < basis.size(); i++) {
1196  basis[i].set_occ_value(occ_index[i]);
1197  }
1198  }
1199 
1200  //***********************************************************
1202 
1203  for(Index i = 0; i < basis.size(); i++) {
1204  basis[i] += shift;
1205  }
1206 
1207  m_factor_group += shift.cart();
1208  return (*this);
1209  }
1210 
1211 
1212  //***********************************************************
1214 
1215  for(Index i = 0; i < basis.size(); i++) {
1216  basis[i] -= shift;
1217  }
1218  m_factor_group -= shift.cart();
1219  return (*this);
1220  }
1221 
1222  //****************************************************
1223 
1225 
1226  // class Structure : public BasicStructure<Site>
1228 
1229  // mutable MasterSymGroup m_factor_group;
1230  json["factor_group"] = m_factor_group;
1231 
1232  // bool SD_flag;
1233  json["SD_flag"] = SD_flag;
1234 
1235  return json;
1236  }
1237 
1238  //****************************************************
1239 
1240  // Assumes constructor CoordType::CoordType(Lattice) exists
1241  void Structure::from_json(const jsonParser &json) {
1242  try {
1243 
1244  // class Structure : public BasicStructure<Site>
1245  BasicStructure<Site> &basic = *this;
1246  basic.from_json(json);
1247 
1248  // mutable MasterSymGroup m_factor_group;
1250  m_factor_group.from_json(json["factor_group"]);
1251 
1252  // bool SD_flag;
1253  CASM::from_json(SD_flag, json["SD_flag"]);
1254 
1255  }
1256  catch(...) {
1258  throw;
1259  }
1260  update();
1261  }
1262 
1263  //****************************************************
1264 
1265  jsonParser &to_json(const Structure &structure, jsonParser &json) {
1266  return structure.to_json(json);
1267  }
1268 
1269  void from_json(Structure &structure, const jsonParser &json) {
1270  structure.from_json(json);
1271  }
1272 
1273  //***********************************************************
1274  /*
1275  Structure operator*(const SymOp &LHS, const Structure &RHS) { //AAB
1276 
1277  return Structure(RHS).apply_sym(LHS);
1278  }
1279  */
1280  //***********************************************************
1281  Structure operator*(const Lattice &LHS, const Structure &RHS) {
1282  Structure tsuper(LHS);
1283  tsuper.fill_supercell(RHS);
1284  return tsuper;
1285  }
1286 
1287 
1288 
1289 
1290 
1291 
1293 
1294 
1297  std::vector< std::vector<Index> > get_index_converter(const Structure &struc, std::vector<Molecule> mol_list) {
1298 
1299  std::vector< std::vector<Index> > converter(struc.basis.size());
1300 
1301  for(Index i = 0; i < struc.basis.size(); i++) {
1302  converter[i].resize(struc.basis[i].site_occupant().size());
1303 
1304  for(Index j = 0; j < struc.basis[i].site_occupant().size(); j++) {
1305  converter[i][j] = find_index(mol_list, struc.basis[i].site_occupant()[j]);
1306  }
1307  }
1308 
1309  return converter;
1310 
1311  }
1312 
1315  std::vector< std::vector<Index> > get_index_converter(const Structure &struc, std::vector<std::string> mol_name_list) {
1316 
1317  std::vector< std::vector<Index> > converter(struc.basis.size());
1318 
1319  for(Index i = 0; i < struc.basis.size(); i++) {
1320  converter[i].resize(struc.basis[i].site_occupant().size());
1321 
1322  for(Index j = 0; j < struc.basis[i].site_occupant().size(); j++) {
1323  converter[i][j] = find_index(mol_name_list, struc.basis[i].site_occupant()[j].name);
1324  }
1325  }
1326 
1327  return converter;
1328 
1329  }
1330 
1335  std::vector< std::vector<Index> > get_index_converter_inverse(const Structure &struc, std::vector<std::string> mol_name_list) {
1336 
1337  std::vector< std::vector<Index> > converter_inv(struc.basis.size());
1338 
1339  for(Index i = 0; i < struc.basis.size(); i++) {
1340  converter_inv[i].resize(mol_name_list.size());
1341 
1342  std::vector<std::string> site_occ_name_list;
1343  for(Index j = 0; j < struc.basis[i].site_occupant().size(); j++) {
1344  site_occ_name_list.push_back(struc.basis[i].site_occupant()[j].name);
1345  }
1346 
1347  for(Index j = 0; j < mol_name_list.size(); j++) {
1348  converter_inv[i][j] = find_index(site_occ_name_list, mol_name_list[j]);
1349  }
1350  }
1351 
1352  return converter_inv;
1353 
1354  }
1355 
1356 };
1357 
1358 
void from_json(const jsonParser &json)
SymGroupRepID basis_permutation_symrep_ID() const
Definition: Structure.cc:113
double angle(const Eigen::Ref< const Eigen::Vector3d > &a, const Eigen::Ref< const Eigen::Vector3d > &b)
Get angle, in radians, between two vectors on range [0,pi].
MasterSymGroup m_factor_group
Definition: Structure.hh:34
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:41
jsonParser & to_json(jsonParser &json) const
void from_json(ClexDescription &desc, const jsonParser &json)
Index size() const
Definition: Array.hh:145
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
Definition: Coordinate.hh:593
Type-safe ID object for communicating and accessing Symmetry representation info. ...
void generate_flowertrees_safe(const SiteOrbitree &in_tree, Array< SiteOrbitree > &out_trees, double tol=TOL)
Gets clusters of every size radiating from one site and saves them to a flowertree. A garland for each site is constructed.
Definition: Structure.cc:562
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.
bool compare(const T &A, const T &B, double tol)
Floating point comparison with tol, return A < B.
Definition: CASM_math.hh:89
const SymGroup & point_group() const
Definition: Structure.cc:101
void push_back(const T &toPush)
Definition: Array.hh:513
const SymGroup & point_group() const
Definition: SymGroup.cc:74
Structure & operator+=(const Coordinate &shift)
Translates all atoms in cell.
Definition: Structure.cc:1201
Structure specifies the lattice and atomic basis of a crystal.
Definition: Structure.hh:29
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
SymGroupRepID generate_basis_permutation_representation(bool verbose=false) const
Obtain the basis permutation representation of factor_group, returns its rep_id, and sets internal ba...
Definition: Structure.cc:1182
void resize(Index new_N)
Definition: Array.hh:468
void generate_factor_group_slow(double map_tol=TOL) const
Obtain factor group by testing all operations of the lattice point_group and keep.
Definition: Structure.cc:77
void copy_attributes_from(const Structure &RHS)
copy all non-derived members
Definition: Structure.cc:62
void generate_flowertrees(const SiteOrbitree &in_tree, Array< SiteOrbitree > &out_trees, double tol=TOL)
Definition: Structure.cc:410
BasicStructure specifies the lattice and atomic basis of a crystal.
Definition: Cluster.hh:16
std::vector< Molecule > get_struc_molecule() const
Returns an Array of each possible Molecule in this Structure.
Definition: Structure.cc:146
Index find_index(Iterator begin, Iterator end, const T &value)
Equivalent to std::distance(begin, std::find(begin, end, value))
Definition: algorithm.hh:16
GenericOrbitBranch< SiteCluster > SiteOrbitBranch
Definition: OrbitBranch.hh:20
Structure stack_on(const Structure &understruc, bool override=0) const
Definition: Structure.cc:692
void fg_converge(double large_tol)
generate factor groups for a range of tol values, prints results to screen (for now) ...
Definition: Structure.cc:231
void set_lattice(const Lattice &new_lat, COORD_TYPE mode)
Definition: Site.cc:202
void generate_factor_group_slow(SymGroup &factor_group, double map_tol) const
Main CASM namespace.
Definition: complete.cpp:8
const Lattice & lattice() const
*bool image_check(const Lattice &cell, int nV=0) const
Checks to see if cluster is "compact" relative to (Lattice cell) in other words, period images of the...
const double TOL
void push_back(const GenericOrbit< ClustType > &new_orbit)
void push_back(const Site &new_site)
Definition: SiteCluster.cc:11
void push_back(const SymOp &op)
Definition: SymGroup.cc:65
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
Definition: Lattice.hh:104
const vector_type & const_cart() const
user override to force const Access the Cartesian coordinate vector
Definition: Coordinate.hh:92
void symmetrize(const SymGroup &relaxed_factors)
Definition: Structure.cc:1022
void generate_factor_group(SymGroup &factor_group, double map_tol) const
apply a symmetry operation to the current structure (may change lattice vectors and order of basis at...
void sort_basis()
Rearrange basis by grouping atoms by type.
Definition: Structure.cc:858
void generate_factor_group(double map_tol=TOL) const
Definition: Structure.cc:85
void get_index() const
Populates 'index', 'index_to_row' and 'index_to_column' Arrays.
const vector_type & const_frac() const
user override to force const Access the fractional coordinate vector
Definition: Coordinate.hh:66
SymGroupRepID basis_perm_rep_ID
This holds the representation id of the permutation representation.
Definition: Structure.hh:36
std::vector< std::string > get_struc_molecule_name() const
Returns an Array of each possible Molecule in this Structure.
Definition: Structure.cc:166
SymGroupRep const * basis_permutation_symrep() const
Definition: Structure.cc:107
bool SD_flag
Specifies whether selectice dynamics is on or of for DFT calculations.
Definition: Structure.hh:38
Index find(const CoordType2 &test_site, double tol=TOL) const
void reset()
clears symmetry, site internals, and other attributes
Definition: Structure.cc:385
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:33
void set_lattice(const Lattice &new_home, COORD_TYPE mode)
Definition: Cluster_impl.hh:21
double tol
void clear()
Definition: Array.hh:216
void print(std::ostream &stream) const
Definition: Site.cc:379
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
const MasterSymGroup & factor_group() const
Definition: Structure.cc:94
BasisSet operator*(const SymOp &LHS, const BasisSet &RHS)
Definition: BasisSet.cc:1154
void print(std::ostream &stream, COORD_TYPE mode=FRAC)
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
void add_vacuum_shift(Structure &new_surface_struc, double vacuum_thickness, Eigen::Vector3d shift, COORD_TYPE mode) const
Add vacuum and shift c vector. The vacuum is always added parallel to c, and the shift vector should ...
Definition: Structure.cc:1088
void collect_basis_info(const Structure &struc)
EigenIndex Index
For long integer indexing:
Structure & operator-=(const Coordinate &shift)
Definition: Structure.cc:1213
void fill_supercell(const Structure &prim, double map_tol=TOL)
fill an empty structure with the basis of its corresponding primitive cell - performs optimized facto...
Definition: Structure.cc:263
void from_json(const jsonParser &json)
Definition: Structure.cc:1241
void add_vacuum(Structure &new_surface_struc, double vacuum_thickness) const
Adds vacuum layer on top of ab plane.
Definition: Structure.cc:1117
Array< Site > basis
Lattice vectors that specifies periodicity of the crystal.
void generate_basis_bouquet(const SiteOrbitree &in_tree, SiteOrbitree &out_tree, Index num_sites, double tol)
Definition: Structure.cc:446
Structure stamp_with(SiteCluster stamp, bool lat_override=0, bool im_override=0) const
Definition: Structure.cc:888
void fg_converge(double small_tol, double large_tol, double increment)
void invalidate_multi_tables() const
Definition: SymGroup.cc:3189
void set_lattice(const Lattice &lattice, COORD_TYPE mode)
Definition: Structure.cc:664
void generate_asym_bouquet(const SiteOrbitree &in_tree, SiteOrbitree &out_tree, Index num_sites, double tol)
Definition: Structure.cc:501
std::string title
User-specified name of this Structure.
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
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
std::vector< std::vector< Index > > get_index_converter(const Structure &struc, std::vector< Molecule > mol_list)
Helper Functions.
Definition: Structure.cc:1297
Structure get_reflection() const
Return reflection of structure.
Definition: Structure.cc:769
GenericOrbit< ClustType > & at(Index ind)
Definition: Array.hh:157
void intpol(Structure end_struc, int Nofimag, PERIODICITY_TYPE mode, Array< Structure > &images)
Definition: Structure.cc:1139
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_no_trans(const SymOp &test_op) const
Check to see if a SymOp is contained in in SymGroup and return its index.
Definition: SymGroup.cc:3309
void print_full_clust(std::ostream &out) const
void from_json(const jsonParser &json)
Definition: SymGroup.cc:4596
void copy_attributes_from(const BasicStructure &RHS)
std::vector< Specie > get_struc_specie() const
Returns an Array of each possible Specie in this Structure.
Definition: Structure.cc:123
Array< Array< Array< double > > > get_NN_table(const double &maxr, SiteOrbitree &bouquet, double tol)
Definition: Structure.cc:965
ClustType & prototype(Index no)
Method to access prototypes.
Array< Structure > bedazzle(Array< SiteCluster > stamps, bool lat_override=0, bool im_override=0) const
Definition: Structure.cc:945
Structure & operator=(const Structure &RHS)
Definition: Structure.cc:40
const Lattice & home() const
Definition: Cluster.hh:42
void generate_orbitree(const Structure &prim, bool verbose=false)
void set_occs(Array< int > occ_index)
Setting the current occupants of the structure to those specified by an array of integers.
Definition: Structure.cc:1190
Eigen::VectorXi get_num_each_molecule() const
Definition: Structure.cc:206
std::vector< std::vector< Index > > get_index_converter_inverse(const Structure &struc, std::vector< std::string > mol_name_list)
Definition: Structure.cc:1335
void reserve(Index new_max)
Definition: Array.hh:491
void pop_back()
Definition: Array.hh:212
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
Definition: Coordinate.hh:581
void map_superstruc_to_prim(Structure &prim)
Figures out which prim basis each superstructure basis corresponds to.
Definition: Structure.cc:605
Array< double > max_length
Definition: Orbitree.hh:51
void set_lattice(const Lattice &new_lat)
Definition: SymGroup.cc:435
SymGroupRep is an alternative representation of a SymGroup for something other than real space...
Definition: SymGroupRep.hh:30
SymGroupRepID generate_basis_permutation_representation(const MasterSymGroup &factor_group, bool verbose) const
void within()
Translate all basis sites so that they are inside the unit cell.
Index size(Index no) const
How many equivalent clusters are int orbit 'no'.
void print_site_symmetry(std::ostream &stream, COORD_TYPE mode, int shorttag, double tol)
For each symmetrically distinct site, print the symmetry operations that map it onto itself...
Definition: Structure.cc:348
void generate_asymmetric_unit(const Array< typename ClustType::WhichCoordType > &basis, const SymGroup &factor_group, double tol)
T & back()
Definition: Array.hh:177
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value) ...
Definition: algorithm.hh:66
void within(Index pivot_ind=0)
Translate entire cluster so that point at(pivot_ind) is inside unit cell.
Basic std::vector like container (deprecated)
void clump_atoms(double maxdist, double tol)
If atoms are too close together, average their distance and make them one.
Definition: Structure.cc:793
void print(std::ostream &stream, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
Index size(Index np) const
Number of orbits in OrbitBranch 'np'.
jsonParser & to_json(jsonParser &json) const
Definition: Structure.cc:1224
Eigen::VectorXi get_num_each_specie() const
Definition: Structure.cc:184
void remove(Index ind)
Definition: Array.hh:546
SymGroupRep const & representation(SymGroupRepID i) const
Const access of alternate Representations of a SymGroup.
Definition: SymGroup.cc:375
virtual BasicStructure & operator=(const BasicStructure &RHS)