CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
Cluster_impl.hh
Go to the documentation of this file.
3 
4 namespace CASM {
5 
6 
7  //****************************************************
8  template <typename CoordType>
10  m_lat_ptr(&init_home),
11  m_min_length(0.0),
12  m_max_length(0.0),
13  m_clust_group(LOCAL) {
14 
15  //nothing else to do for now
16  }
17 
18  //****************************************************
19 
20  template <typename CoordType>
22  if(m_lat_ptr == &new_home)
23  return;
24  m_lat_ptr = &new_home;
25  for(Index i = 0; i < size(); i++)
26  at(i).set_lattice(new_home, mode);
27 
28  return;
29  }
30 
31  //****************************************************
32  template <typename CoordType>
34  Index basis_ind;
35  for(Index i = 0; i < (*this).size(); i++) {
36  basis_ind = ref_struc.find(at(i));
37  if(basis_ind >= ref_struc.basis.size()) {
38  std::cerr << "ERROR in GenericCluster<CoordType>::set_occupant_basis. Could not "
39  << "find a basis site in ref_struc that corresponds to site " << i
40  << "QUITTING" << std::endl;
41  std::cerr << "DEBUGGING info: " << std::endl;
42  print(std::cerr);
43  //std::cerr<<"The structure is:"<<std::endl;
44  //ref_struc.print(std::cerr);
45  exit(666);
46  }
47  (*this).at(i).update_data_members(ref_struc.basis[basis_ind]);
48  }
49  return;
50  }
51 
52  //********************************************
53 
54  template <typename CoordType>
56  if(iperm.size() != size()) {
57  std::cerr << "WARNING: Attempted to permute points of cluster of size " << size() << " using a permutation of " << iperm.size() << " indicies.\n";
58  return *this;
59  }
61 
62  return *this;
63  }
64 
65  //********************************************
66 
67  template <typename CoordType>
69  return permute(perm.perm_array());
70  }
71 
72  //********************************************
73  template <typename CoordType>
75  for(Index i = 0; i < size(); i++)
76  at(i).apply_sym(op);
77 
78  m_clust_group.apply_sym(op);
79  return *this;
80  }
81 
82  //********************************************
83 
84  template <typename CoordType>
86  for(Index i = 0; i < size(); i++)
87  at(i).apply_sym_no_trans(op);
88 
89  m_clust_group.apply_sym(op);
90  return *this;
91  }
92 
93 
94  //*******************************************************************************************
95  // Assuming that we have the factor group (or some similar group),
96  // what are the operations that leave the cluster unchanged
97  // Find them, alter the translations, and store them in clust_group
98 
99  template <typename _CoordType>
100  void GenericCluster<_CoordType>::generate_clust_group(const SymGroup &super_group, std::vector<Permutation> *perm_array_ptr, double tol) {
101  Coordinate trans(home());
102  _clust_group().clear();
103  if(perm_array_ptr)
104  perm_array_ptr->clear();
105  Array<Index> iperm;
106  for(Index ng = 0; ng < super_group.size(); ng++) {
107  GenericCluster<_CoordType> tclust(*this);
108  tclust.apply_sym(super_group[ng]);
109  if(tclust.map_onto(*this, trans)) {
110  _clust_group().push_back(SymOp::translation(trans.cart())*super_group[ng]);
111  find(tclust, iperm, tol);
112 
113  if(perm_array_ptr)
114  perm_array_ptr->push_back(Permutation(iperm));
115  }
116  }
117 
118  return;
119  }
120 
121  //*******************************************************************************************
122 
123  template <typename _CoordType>
124  std::vector<Permutation> GenericCluster<_CoordType>::clust_group_permutations(double tol) const {
125  std::vector<Permutation> tperms;
126  tperms.reserve(clust_group().size());
127  Array<Index> iperm(size());
128  for(Index i = 0; i < clust_group().size(); i++) {
129  for(Index j = 0; j < size(); j++)
130  iperm[j] = find(clust_group()[i] * at(j), tol);
131  tperms.push_back(Permutation(iperm));
132  }
133  return tperms;
134  }
135 
136  //********************************************
137 
138  template <typename CoordType>
140 
141  if(!size() || PERIODICITY_MODE::IS_LOCAL()) return;
142 
143  if(pivot_ind >= size()) {
144  std::cerr << "WARNING: Attempted to map cluster within unit cell with invalid pivot." << std::endl;
145  return;
146  }
147 
148  Coordinate tcoord(*m_lat_ptr);
149  at(pivot_ind).within(tcoord);
150  for(Index i = 0; i < size(); i++) {
151  if(i != pivot_ind)
152  at(i) += tcoord;
153  }
154 
155  return;
156  }
157 
158  //********************************************
159 
160  template <typename CoordType>
162 
163  if(!size() || PERIODICITY_MODE::IS_LOCAL()) return;
164 
165  if(pivot_ind >= size()) {
166  std::cerr << "WARNING: Attempted to map cluster within unit cell with invalid pivot." << std::endl;
167  return;
168  }
169 
170  trans.set_lattice(*m_lat_ptr, CART);
171  at(pivot_ind).within(trans);
172  for(Index i = 0; i < size(); i++) {
173  if(i != pivot_ind)
174  at(i) += trans;
175  }
176 
177  return;
178  }
179 
180  //********************************************
181 
182  template <typename CoordType>
184  // should all_within check the periodicity mode?
185  // It will probably be used in situations where periodicity_mode is local
186  // but where normal functionality is desired.
187  // e.g., mapping local clusters onto a supercell configuration
188  if(PERIODICITY_MODE::IS_LOCAL()) return;
189  for(Index i = 0; i < size(); i++)
190  at(i).within();
191  return;
192  }
193 
194  //********************************************
195  // Returns true if a vector can be found connecting one site of the cluster
196  // to a periodic image of the cluster that is shorter than at least one of the
197  // vectors connecting two sites of the cluster, assuming the periodic boundaries
198  // defined by Lattice given by 'cell'
199 
200  template <typename CoordType>
201  bool GenericCluster<CoordType>::image_check(const Lattice &cell, int max_nV) const {
202  Coordinate tcoord(*m_lat_ptr);
203  Index i, j;
204  int tnV;
205  for(i = 0; i < size(); i++) {
206  for(j = i + 1; j < size(); j++) {
207  tcoord = at(j) - at(i);
208  tnV = tcoord.voronoi_number(cell);
209  if(tnV > max_nV || tnV < 0)
210  return true;
211  }
212  }
213  return false;
214  }
215 
216 
217  //********************************************
218 
219  template <typename CoordType>
221  if(!size())
222  return Coordinate(*m_lat_ptr);
223 
224  Coordinate tcoord(at(0));
225  for(Index i = 1; i < size(); i++) {
226  tcoord += at(i);
227  }
228  tcoord.cart() /= size();
229  return tcoord;
230  }
231 
232  //********************************************
233 
234  template <typename CoordType>
236  Index i, j;
237  for(i = 0; i < test_cluster.size(); i++) {
238  for(j = 0; j < size(); j++) {
239  if(test_cluster[i] == at(j))
240  break;
241  }
242  if(j == size())
243  return false;
244  }
245  return true;
246  }
247 
248  //********************************************
249 
250  template <typename CoordType>
251  bool GenericCluster<CoordType>::contains_periodic(const CoordType &test_site, double tol) const {
252  for(Index i = 0; i < size(); i++) {
253  if(at(i).compare(test_site, tol))
254  return true;
255  }
256  return false;
257  }
258  //********************************************
259  //returns true if test_cluster is a subcluster of cluster (*this)
260  //Array 'index' holds indices of (*this) that yield test_cluster
261  template <typename CoordType>
262  Index GenericCluster<CoordType>::find(const CoordType &test_elem, double tol) const {
263  Index j;
264 
265  for(j = 0; j < size(); j++) {
266  if(test_elem.almost_equal(at(j), tol))
267  return j;
268  }
269 
270  return j;
271  }
272  //********************************************
273  //returns true if test_cluster is a subcluster of cluster (*this)
274  //Array 'index' holds indices of (*this) that yield test_cluster
275  template <typename CoordType>
276  bool GenericCluster<CoordType>::find(const GenericCluster<CoordType> &test_cluster, Array<Index> &index, double tol) const {
277  Index i, j;
278  index.clear();
279  index.reserve(test_cluster.size());
280  for(i = 0; i < test_cluster.size(); i++) {
281  for(j = 0; j < size(); j++) {
282  if(test_cluster[i].almost_equal(at(j), tol) && !index.contains(j))
283  break;
284  }
285  if(j == size()) {
286  index.clear();
287  return false;
288  }
289  index.push_back(j);
290  }
291  return true;
292  }
293 
294  //********************************************
295  //This routine needs to be edited so that when sites are reordered,
296  //the cluster basis functions are updated to reflect the change in order
297 
298  template <typename CoordType>
300  Index i, j, tsize;
301 
302  if(!(home() == pivot.home())) {
303  std::cerr << "WARNING in Cluster::map_onto_subcluser!!\n"
304  << "You are trying to map a pivot onto a cluster with\n"
305  << "a different lattice! \n";
306  }
307 
308 
309  if(PERIODICITY_MODE::IS_LOCAL() && size() > 1) tsize = 1;
310  else tsize = size();
311 
312  Array<Index> tarray, tperm(size(), 0);
313 
314  for(i = 0; i < tsize; i++) {
315  Coordinate ttrans(at(i) - pivot[0]);
316  if(ttrans.is_lattice_shift() && ((at(i) - ttrans) == pivot[0])) {
317  (*this) -= ttrans;
318  }
319  else
320  continue; //If not a lattice translation, move onto the next site
321 
322 
323 
324  //Following checks true/false condition
325  //if condition is true, then sites are reordered so that first N sites of current cluster
326  //match the N sites of 'pivot', in order
327 
328  if(find(pivot, tarray, tol)) {
329  Index t_ind, n_switch(0);
330  for(j = 0; j < tperm.size(); j++) {
331  t_ind = tarray.find(j);
332  if(t_ind < tarray.size()) {
333  tperm[t_ind] = j;
334 
335  }
336  else {
337  tperm[tarray.size() + n_switch] = j;
338  n_switch++;
339  }
340 
341  }
342  permute(tperm);
343  return true;
344  }
345  }
346  return false;
347  }
348 
349  //********************************************
350  //This routine needs to be edited so that when sites are reordered,
351  //the cluster basis functions are updated to reflect the change in order
352  //num_maps should be from 0 to size of the cluster
353  //returns true if successful maps == num_maps
354  template <typename CoordType>
356  Index i, j, tsize;
357 
358  if(!(home() == pivot.home())) {
359  std::cerr << "WARNING in Cluster::map_onto_subcluser!!\n"
360  << "You are trying to map a pivot onto a cluster with\n"
361  << "a different lattice! \n";
362  }
363 
364 
365  if(PERIODICITY_MODE::IS_LOCAL() && size() > 1) tsize = 1;
366  else tsize = size();
367 
368  Array<Index> tarray, tperm(size(), 0);
369  int tmaps(0);
370  for(i = 0; i < tsize; i++) {
371  Coordinate ttrans(at(i) - pivot[0]);
372  if(ttrans.is_lattice_shift() && ((at(i) - ttrans) == pivot[0])) {
373  (*this) -= ttrans;
374  }
375  else continue; //If not a lattice translation, move onto the next site
376 
377 
378 
379  //Following checks true/false condition
380  //if condition is true, then sites are reordered so that first N sites of current cluster
381  //match the N sites of 'pivot', in order
382 
383  if(!find(pivot, tarray, tol))continue;
384  if(tmaps != num_maps) {
385  tmaps++;
386  continue;
387  }
388  Index t_ind, n_switch(0);
389  for(j = 0; j < tperm.size(); j++) {
390  t_ind = tarray.find(j);
391  if(t_ind < tarray.size()) {
392  tperm[t_ind] = j;
393 
394  }
395  else {
396  tperm[tarray.size() + n_switch] = j;
397  n_switch++;
398  }
399 
400  }
401  permute(tperm);
402  return true;
403 
404  }
405  return false;
406  }
407 
408  //********************************************************************
409 
410  template <typename CoordType>
412  for(Index ns = 0; ns < size(); ns++) {
413  at(ns).set_basis_ind(-1);
414  for(Index nb = 0; nb < basis.size(); nb++) {
415  if(at(ns).compare(basis[nb], shift)) {
416  at(ns).set_basis_ind(nb);
417  break;
418  }
419  }
420  if(!valid_index(at(ns).basis_ind())) {
421  std::cerr << "WARNING in GenericCluster::collect_basis_info" << std::endl;
422  std::cerr << "Could not get basis info for " << at(ns) << std::endl;
423  return;
424  }
425  }
426  }
427 
428  //********************************************************************
429 
430  template <typename CoordType>
432  for(Index ns = 0; ns < size(); ns++) {
433  at(ns).set_basis_ind(-1);
434  for(Index nb = 0; nb < basis.size(); nb++) {
435  if(at(ns).compare(basis[nb])) {
436  at(ns).set_basis_ind(nb);
437  break;
438  }
439  }
440  if(!valid_index(at(ns).basis_ind())) {
441  std::cerr << "WARNING in GenericCluster::collect_basis_info" << std::endl;
442  std::cerr << "Could not get basis info for " << at(ns) << std::endl;
443  return;
444  }
445  }
446  }
447 
448  //********************************************
455  //********************************************
456  template <typename CoordType>
457  void GenericCluster<CoordType>::read(std::istream &stream, COORD_TYPE mode) {
458 
459  Index np;
460  CoordType t_coord(*m_lat_ptr);
461  std::string tstring;
462  char tchar[256];
463  char ch;
464 
465  ch = stream.peek();
466 
467 #ifdef DEBUG
468  std::cout << "INSIDE CLUSTER READ \n";
469  std::cout << "char(35) is " << char(35) << "\n";
470 #endif //DEBUG
471 
472  while((ch != char(35))) {
473 #ifdef DEBUG
474  std::cout << "looking for # ch is " << ch << "\n";
475 #endif //DEBUG
476  stream.ignore(1000, '\n');
477  ch = stream.peek();
478  }
479 
480  stream.getline(tchar, 1000, ':');
481  stream >> np;
482 
483 #ifdef DEBUG
484  std::cout << "np is " << np << "\n";
485 #endif //DEBUG
486 
487  ch = stream.peek();
488  while((ch != 'M') && (ch != 'm')) {
489  stream.ignore(1000, '\n');
490  ch = stream.peek();
491  }
492 
493 #ifdef DEBUG
494  std::cout << "GOING TO TRY TO READ MAX MIN LENGTHS\n";
495 #endif //DEBUG
496 
497  stream.getline(tchar, 1000, ':'); //Changed from = to :
498  stream >> m_max_length;
499  stream.getline(tchar, 1000, ':');
500  stream >> m_min_length;
501 
502 #ifdef DEBUG
503  std::cout << "m_max_length is " << m_max_length << "\n";
504  std::cout << "m_min_length is " << m_min_length << "\n";
505 #endif //DEBUG
506 
507 
508  COORD_MODE input_mode(mode);
509 
510  for(Index i = 0; i < np; i ++) {
511  t_coord.read(stream);
512  push_back(t_coord);
513  }
514 
515  return;
516 
517 
518  }
519 
520  //********************************************
521 
522  template <typename CoordType>
523  void GenericCluster<CoordType>::push_back(const CoordType &new_coord) {
524 
525  Array<CoordType>::push_back(new_coord);
526 
527  if(!m_lat_ptr)
528  m_lat_ptr = &back().home();
529 
530  else if(&(back().home()) != m_lat_ptr)
531  back().set_lattice(*m_lat_ptr, CART);
532 
533  return;
534  }
535 
536  //********************************************
538 
539  template <typename CoordType>
541  for(Index i = 0; i < RHS.size(); i++) {
542  if(!contains(RHS[i]))
543  push_back(RHS[i]);
544  }
545  return;
546  }
547 
548 
549  //********************************************
550 
551  template <typename CoordType>
553  for(Index i = 0; i < size(); i++)
554  at(i) += RHS;
555  return *this;
556  }
557 
558  //********************************************
559 
560  template <typename CoordType>
562  for(Index i = 0; i < size(); i++)
563  at(i) -= RHS;
564  return *this;
565  }
566 
567  //********************************************
568 
569  template <typename CoordType>
571  if(size() != RHS.size()) return false;
572 
573  Array<bool> check_ind(size(), false);
574  Index i, j;
575  for(i = 0; i < size(); i++) {
576  for(j = 0; j < RHS.size(); j++) {
577  if((at(i) == RHS[j]) && (!check_ind[j])) {
578  check_ind[j] = true;
579  break;
580  }
581  }
582  if(j == RHS.size())
583  return false;
584  }
585  return true;
586  }
587 
588  //********************************************
589 
590  template <typename CoordType>
592  if(size() != test_clust.size()) return false;
593  if(PERIODICITY_MODE::IS_LOCAL()) return (*this) == test_clust;
594 
595  GenericCluster<CoordType> tclust(*this);
596  for(Index i = 0; i < tclust.size(); i++) {
597  tclust.within(i);
598  if(tclust == test_clust) {
599  return true;
600  }
601  }
602  return false;
603  }
604 
605  //********************************************
606 
607  template <typename CoordType>
609  if(size() != test_clust.size()) return false;
610  if(PERIODICITY_MODE::IS_LOCAL()) return (*this) == test_clust;
611 
612  GenericCluster<CoordType> tclust(*this);
613  for(Index i = 0; i < tclust.size(); i++) {
614  tclust.within(i, trans);
615  if(tclust == test_clust) {
616  return true;
617  }
618  }
619  return false;
620  }
621 
622  //********************************************
623  //Checks for lattice translations that map the cluster onto test_clust
624  //map_onto(...) is non-const, and if it returns true, the cluster
625  //has been translated onto test_clust, although the points may be ordered differently.
626  //If it returns false, the cluster is unchanged.
627 
628  template <typename CoordType>
630  if(size() != test_clust.size()) return false;
631  if(size() == 0) return true;
632 
633  //If non-periodic, translations need not be considered
634  if(PERIODICITY_MODE::IS_LOCAL()) return (*this) == test_clust;
635 
636  //tshift keeps track of translations
637  Coordinate tshift(*m_lat_ptr), trans(*m_lat_ptr);
638  for(Index i = 0; i < size(); i++) {
639  tshift = test_clust[0] - at(i);
640  if(tshift.is_lattice_shift(tol)) {
641  (*this) += tshift;
642  trans += tshift;
643  if(almost_equal((*this), test_clust, tol))
644  return true;
645  }
646  }
647  (*this) -= trans;
648  return false;
649  }
650 
651  //********************************************
652 
653  template <typename CoordType>
655  if(size() != test_clust.size()) return false;
656  trans.frac() = Eigen::Vector3d::Zero();
657  if(size() == 0) return true;
658 
660  return (*this) == test_clust;
661  }
662 
663  Coordinate tshift(*m_lat_ptr);
664  for(Index i = 0; i < size(); i++) {
665  tshift = test_clust[0] - at(i);
666  if(tshift.is_lattice_shift(tol)) {
667  (*this) += tshift;
668  trans += tshift;
669  if(almost_equal((*this), test_clust, tol))
670  return true;
671  }
672  }
673  (*this) -= trans;
674  trans.frac() = Eigen::Vector3d::Zero();
675  return false;
676  }
677 
678  //********************************************
679 
680  template <typename CoordType>
682  double tlength;
683 
684  //Point clusters don't have a max_length - (is this necessary?)
685  if(size() <= 1)
686  m_max_length = m_min_length = 0;
687 
688  else if(size() > 1) {
689  //Establish max and min as distance from first set
690  m_max_length = m_min_length = at(0).dist(at(1));
691 
692  for(Index i = 0; i < size(); i++) {
693  for(Index j = i + 1; j < size(); j++) {
694  tlength = at(i).dist(at(j));
695  if(tlength < m_min_length)
696  m_min_length = tlength;
697  if(tlength > m_max_length)
698  m_max_length = tlength;
699  }
700  }
701  }
702  return;
703  }
704 
705 
706 
707  //********************************************
714  //************************************************************
715 
716  template <typename CoordType>
718  double dist;
719 
720  // calculate min/max lengths relative the phenom_clust & this cluster
721  m_max_length = 0;
722  m_min_length = 1e20;
723 
724  // first check distances to phenom_clust
725  for(Index i = 0; i < size(); i++) {
726  for(Index k = 0; k < phenom_clust.size(); k++) {
727  dist = phenom_clust[k].dist(at(i));
728  if(dist > m_max_length)
729  m_max_length = dist;
730  if(dist < m_min_length) // only set min_length for length between sites in the cluster
731  m_min_length = dist;
732 
733  }
734  }
735 
736  // then to sites in this cluster
737  for(Index i = 0; i < size(); i++) {
738  for(Index k = i + 1; k < size(); k++) {
739  dist = at(k).dist(at(i));
740  if(dist > m_max_length)
741  m_max_length = dist;
742  if(dist < m_min_length)
743  m_min_length = dist;
744 
745  }
746  }
747 
748  //std::cout << " max_length: " << m_max_length << " min_length: " << m_min_length << endl;
749 
750  return;
751  }
752 
753  //********************************************
754 
755  template <typename CoordType>
756  void GenericCluster<CoordType>::print(std::ostream &stream, char delim, COORD_TYPE mode) const {
757  if(mode == COORD_DEFAULT)
758  mode = COORD_MODE::CHECK();
759  COORD_MODE C(mode);
760 
761  stream << "#Points: " << size() << std::endl
762  << "MaxLength: " << m_max_length << " MinLength: " << m_min_length << std::endl;
763  for(Index np = 0; np < size(); np++) {
764  stream.setf(std::ios::showpoint, std::ios_base::fixed);
765  stream.precision(5);
766  stream.width(9);
767  at(np).print(stream);//Changed by Ivy from at(np).print(stream,mode) -- the "mode" should actually be the SD_flag input 11/04/12
768  if(delim)
769  stream << delim;
770  }
771  }
772 
773  //********************************************
774 
775  template <typename CoordType>
776  void GenericCluster<CoordType>::print_shifted(std::ostream &stream, const Coordinate &shift, char delim, COORD_TYPE mode) const {
777  if(mode == COORD_DEFAULT)
778  mode = COORD_MODE::CHECK();
779  COORD_MODE C(mode);
780 
781  stream << "#Points: " << size() << std::endl
782  << "MaxLength: " << m_max_length << " MinLength: " << m_min_length << std::endl;
783  for(Index np = 0; np < size(); np++) {
784  stream.setf(std::ios::showpoint, std::ios_base::fixed);
785  stream.precision(5);
786  stream.width(9);
787  (at(np) + shift).print(stream); //Changed by Ivy from at(np).print(stream,mode) -- the "mode" should actually be the SD_flag input 11/04/12
788  if(delim)
789  stream << delim;
790  }
791 
792  }
793 
794  //********************************************
795 
796  template <typename CoordType>
797  void GenericCluster<CoordType>::print_sites(std::ostream &stream, int space, char delim, COORD_TYPE mode) const {
798  if(mode == COORD_DEFAULT)
799  mode = COORD_MODE::CHECK();
800  COORD_MODE C(mode);
801  for(Index np = 0; np < size(); np++) {
802  for(int i = 0; i < space; i++) {
803  stream << ' ';
804  }
805  stream.setf(std::ios::showpoint, std::ios_base::fixed);
806  stream.precision(5);
807  stream.width(9);
808  at(np).print(stream);//Changed by Ivy from at(np).print(stream,mode) -- the "mode" should actually be the SD_flag input 11/04/12
809  if(delim)
810  stream << delim;
811  }
812  }
813 
814  //********************************************
815 
816  template <typename CoordType>
817  void GenericCluster<CoordType>::print_basis_info(std::ostream &stream, int space, char delim, COORD_TYPE mode) const {
818  if(mode == COORD_DEFAULT)
819  mode = COORD_MODE::CHECK();
820  COORD_MODE C(mode);
821  for(Index np = 0; np < size(); np++) {
822  for(int i = 0; i < space; i++) {
823  stream << ' ';
824  }
825  stream.setf(std::ios::showpoint, std::ios_base::fixed);
826  stream.precision(5);
827  stream.width(9);
828  at(np).print(stream);
829  stream << " " << at(np).basis_ind() << " ";
830  if(delim)
831  stream << delim;
832  }
833  }
834 
835  //********************************************
836 
837  template <typename CoordType>
838  void GenericCluster<CoordType>::print_decorated_sites(std::ostream &stream, int space, char delim, COORD_TYPE mode) const {
839  if(mode == COORD_DEFAULT)
840  mode = COORD_MODE::CHECK();
841  COORD_MODE C(mode);
842  for(Index np = 0; np < size(); np++) {
843  for(int i = 0; i < space; i++) {
844  stream << ' ';
845  }
846  stream.setf(std::ios::showpoint, std::ios_base::fixed);
847  stream.precision(5);
848  stream.width(9);
849  at(np).print_occ(stream);//Changed by Ivy from at(np).print(stream,mode) -- the "mode" should actually be the SD_flag input 11/04/12
850  if(delim)
851  stream << delim;
852  }
853  }
854 
855  //********************************************
859  //********************************************
860  template <typename CoordType>
861  std::ostream &operator<< (std::ostream &stream, const GenericCluster<CoordType> &cluster) {
862  cluster.print(stream, '\n'); //Ivy added newline delimiter 07/01/13
863  return stream;
864  }
865 
866 
867  //****************************************************
868  template <typename CoordType>
870  return GenericCluster<CoordType>(RHS).apply_sym(LHS);
871  }
872 
873  //****************************************************
874  template <typename CoordType>
876  return GenericCluster<CoordType>(LHS) += RHS;
877  }
878 
879 
880  //****************************************************
881  template <typename CoordType>
883  return GenericCluster<CoordType>(LHS) -= RHS;
884  }
885 
886  //****************************************************
887  template <typename CoordType>
889  if(LHS.size() != RHS.size()) return false;
890 
891  Array<bool> check_ind(LHS.size(), false);
892  Index i, j;
893  for(i = 0; i < LHS.size(); i++) {
894  for(j = 0; j < RHS.size(); j++) {
895  if((LHS[i].almost_equal(RHS[j], tol)) && (!check_ind[j])) {
896  check_ind[j] = true;
897  break;
898  }
899  }
900  if(j == RHS.size())
901  return false;
902  }
903  return true;
904 
905 
906  }
907 
908 
909 
910 }
void print_basis_info(std::ostream &stream, int space, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
static SymOp translation(const Eigen::Ref< const vector_type > &_tau)
static method to create operation that describes pure translation
Definition: SymOp.hh:35
bool contains(const T &test_elem) const
Definition: Array.hh:281
Index size() const
Definition: Array.hh:145
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
Definition: Coordinate.hh:593
bool is_lattice_shift(double tol=TOL) const
Checks to see if coordinate is at a lattice translation with respect to the origin.
Definition: Coordinate.cc:367
void push_back(const T &toPush)
Definition: Array.hh:513
void push_back(const CoordType &new_coord)
const Array< Index > & perm_array() const
Definition: Permutation.hh:57
BasicStructure specifies the lattice and atomic basis of a crystal.
Definition: Cluster.hh:16
Main CASM namespace.
Definition: complete.cpp:8
*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...
bool contains_periodic(const CoordType &test_coord, double tol) const
Like Array::contains(), but takes periodicity mode into account.
void collect_basis_info(const Array< CoordType > &basis)
Figure out which basis atoms in basis correspond to the points in cluster (*this) ...
void print_sites(std::ostream &stream, int space, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
GenericCluster< CoordType > operator+(const GenericCluster< CoordType > &LHS, const Coordinate &RHS)
create translated cluster
GenericCluster & operator-=(const Coordinate &RHS)
GenericCluster< CoordType > operator-(const GenericCluster< CoordType > &LHS, const Coordinate &RHS)
create translated cluster
Index find(const CoordType2 &test_site, double tol=TOL) const
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:33
GenericCluster(const Lattice &init_home)
Definition: Cluster_impl.hh:9
void set_lattice(const Lattice &new_home, COORD_TYPE mode)
Definition: Cluster_impl.hh:21
GenericCluster & permute(const Array< Index > &perm)
permute sites of the cluster, and everything that depends on the site order
Definition: Cluster_impl.hh:55
double tol
int voronoi_number() const
Definition: Coordinate.cc:317
void clear()
Definition: Array.hh:216
void print_shifted(std::ostream &stream, const Coordinate &shift, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
COORD_MODE specifies the current coordinate mode (Fractional or Cartesian)
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
BasisSet operator*(const SymOp &LHS, const BasisSet &RHS)
Definition: BasisSet.cc:1154
void calc_properties()
gets max_length and min_length
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
GenericCluster & apply_sym_no_trans(const SymOp &op)
apply symmetry to all points of the cluster without translation
Definition: Cluster_impl.hh:85
EigenIndex Index
For long integer indexing:
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
std::vector< Permutation > clust_group_permutations(double tol) const
Finds the Permutation corresponding to each element of clust_group.
Coordinate geometric_center() const
Returns the geometric center of "mass" of a cluster (treats all sites as having equal mass) ...
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
Definition: algorithm.hh:10
GenericCluster & operator+=(const Coordinate &RHS)
in=place translation of a cluster
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
void update_data_members(const BasicStructure< CoordType > &ref_struc)
Definition: Cluster_impl.hh:33
Index find(const T &test_elem) const
Definition: Array.hh:707
void all_within()
Map every point of cluster inside unit cell.
bool is_equivalent(const GenericCluster &test_clust) const
are two clusters identical, to within permutation and translation
const Lattice & home() const
Definition: Cluster.hh:42
void reserve(Index new_max)
Definition: Array.hh:491
GenericCluster & apply_sym(const SymOp &op)
apply symmetry to all points of the cluster
Definition: Cluster_impl.hh:74
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
Definition: Coordinate.hh:581
void generate_clust_group(const SymGroup &super_group, std::vector< Permutation > *perm_array_ptr=nullptr, double tol=TOL)
Finds the sub_group of super_group that is the point group of the cluster.
void read(std::istream &stream, int num_sites, COORD_TYPE mode, bool SD_is_on)
bool map_onto_subcluster(const GenericCluster &pivot, double tol=TOL)
void print_decorated_sites(std::ostream &stream, int space, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
void merge(const GenericCluster &RHS)
adds unique points of 'RHS' to (*this)
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.
Index find(const CoordType &test_elem, double tol) const
is test_cluster a subcluster of (*this), and how do the indices map points of test_cluster ...
bool operator==(const GenericCluster &RHS) const
are two clusters identical, to within a permutation
bool almost_equal(const GenericCluster< CoordType > &LHS, const GenericCluster< CoordType > &RHS, double tol)
bool map_onto(const GenericCluster &test_clust, double tol)
if is_equivalent(test_clust) is true, return true and map (*this) onto test_clust ...
void print(std::ostream &stream, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
Array & permute(const Array< Index > &perm_array)
Definition: Array.hh:923
bool contains(const GenericCluster &test_cluster) const
is test_cluster a subcluster of (*this)
bool valid_index(Index i)
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())