CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
OrbitBranch_impl.hh
Go to the documentation of this file.
1 namespace CASM {
2  //********************************************************************
3 
4  template<typename ClustType>
7  pivot.clear();
8  index.clear();
9  m_num_sites = 0;
10  }
11 
12  //********************************************************************
13 
14  template<typename ClustType>
16  return at(no);
17  }
18 
19  //********************************************************************
20 
21  template<typename ClustType>
23  return at(no);
24  }
25 
26  //********************************************************************
27 
28  template<typename ClustType>
29  const ClustType &GenericOrbitBranch<ClustType>::prototype(Index no) const {
30  return at(no).prototype;
31  }
32 
33  //********************************************************************
34 
35  template<typename ClustType>
37  return at(no).prototype;
38  }
39 
40  //********************************************************************
41 
42  template<typename ClustType>
43  const ClustType &GenericOrbitBranch<ClustType>::equiv(Index no, Index ne) const {
44  return at(no).at(ne);
45  }
46 
47  //********************************************************************
48 
49  template<typename ClustType>
51  return at(no).at(ne);
52  }
53 
54  //********************************************************************
55 
56  template<typename ClustType>
58  return at(no).size();
59  }
60 
61  //********************************************************************
62 
63  template<typename ClustType>
65  for(Index no = 0; no < size(); no++)
66  orbit(no).set_lattice(new_lat, mode);
67  pivot.set_lattice(new_lat, mode);
68  return;
69  }
70 
71  //*******************************************************************************************
72 
73  template<typename ClustType>
74  void GenericOrbitBranch<ClustType>::set_pivot(const ClustType &new_pivot) {
75  if(&(pivot.home()) != &(new_pivot.home())) {
76  std::cerr << "WARNING!!! In GenericOrbitBranch::set_pivot(), the new 'pivot' clust has a different home lattice than the old pivot cluster.\n"
77  << " This may result in unexpected behavior!\n";
78  assert(0);
79  set_lattice(new_pivot.home(), CART); // <-- this makes it slightly safer
80  pivot = new_pivot;
81  }
82 
83  pivot = new_pivot;
84 
85  }
86  //********************************************************************
87 
88  template<typename ClustType>
90  if(num_sites() < 0)
91  m_num_sites = new_orbit.prototype.size();
92 
93  else if(num_sites() != new_orbit.prototype.size()) {
94  std::cerr << "WARNING: Trying to add " << new_orbit.prototype.size()
95  << "-site Orbit to an OrbitBranch intended for " << num_sites()
96  << "-site Orbits. Continuing...\n";
97  return;
98  }
99 
100  Array< GenericOrbit<ClustType> >::push_back(new_orbit);
101  return;
102  }
103 
104  //********************************************************************
105 
106  template<typename ClustType>
108  for(Index no = 0; no < size(); no++)
109  at(no).apply_sym(op);
110  pivot.apply_sym(op);
111  return *this;
112  }
113 
114  //********************************************************************
115  template<typename ClustType>
116  void GenericOrbitBranch<ClustType>::print(std::ostream &stream, COORD_TYPE mode) {
117  /*Mainly will be used for print out the asymmetric
118  * unit, however will print any orbitbranch.
119  * First, loop over the outer branch, the size
120  * of which is the number of atoms in the asymmetric unit.
121  * Then, loop over each point in this branch to print out
122  * the symmetrically equivalent points
123  */
124  stream << "-----------------------------------------------\n";
125  for(Index i = 0; i < size(); i++) {
126  stream << "Asymmetric Point # " << i + 1 << " of " << size() << ":\n";
127  /*Print the unique point (first item in the branch we're currently in)
128  * at(i).at(0) points to this, which should be a cluster... How do we just print the cluster?
129  * GenericOrbitBranch<Site>, Array<SiteOrbit<Site>> --> Array< Array<GenericCluster<Site>> --> Array<Array<Array<Site>>>
130  */
131  at(i).at(0).at(0).print_occ(stream); //Since we only have one item in the cluster, can print the 1st thing in it (the second at(0) ) to JUST print the site info, not the cluster info
132 
133  stream << "\n\nEquivalent points are: \n";
134 
135  for(Index j = 1; j < at(i).size(); j++) { //Loop over all the equivalent points and print them
136  stream << " "; //Indent all of the equivalent points
137  at(i).at(j).at(0).print_occ(stream);
138  stream << "\n";
139  }
140 
141  stream << "\n";
142  stream << "-----------------------------------------------\n";
143 
144  }
145  }
146 
147  //********************************************************************
148 
149  template<typename ClustType>
151  for(Index i = 0; i < size(); i++) { //Loops over the inner array, which is the subset of all the same-sized clusters
152  for(Index j = i + 1; j < size(); j++) { //Takes the next-in-line of the inner array and compares it
153  // if(orbit(i).prototype.max_length > orbit(j).prototype.max_length){
154  if(std::abs(orbit(i).max_length() - orbit(j).max_length()) < TOL && orbit(i).min_length() > orbit(j).min_length()) {
155  GenericOrbit<ClustType> torbit(orbit(j));
156  orbit(j) = orbit(i);
157  orbit(i) = torbit;
158  }
159  else if(orbit(i).max_length() > orbit(j).max_length() + TOL) {
160  GenericOrbit<ClustType> torbit(orbit(j));
161  orbit(j) = orbit(i);
162  orbit(i) = torbit;
163  }
164  }
165  }
166  }
167  //*******************************
168 
169  template<typename ClustType>
170  Index GenericOrbitBranch<ClustType>::find(const ClustType &test_clust, double tol) const {
171  for(Index i = 0; i < size(); i++) {
172  if(orbit(i).contains(test_clust, tol))
173  return i;
174  }
175  return size();
176  }
177 
178  //*******************************
179 
180  template<typename ClustType>
181  bool GenericOrbitBranch<ClustType>::contains(const ClustType &test_clust, double tol) const {
182  if(size() == 0) return false;
183 
184  if(find(test_clust, tol) < size()) {
185  return true;
186  }
187  return false;
188 
189  }
190 
191  //***********************************************************
192 
193  template<typename ClustType>
195  m_num_sites = 1;
196  if(size() != 0) { //Added by Ivy 11/19/13
197 
198  std::cerr << "WARNING in GenericOrbitBranch::generate_asymmetric_unit()\n"
199  << "This OrbitBranch is not empty\n"
200  << "and is about to be overwritten!\n";
201 
202  clear();
203 
204  }
205 
206  if(basis.size() == 0)
207  return;
208  set_lattice(basis[0].home(), FRAC);
209  ClustType tclust(basis[0].home());
210  Index nb, no;
211 
212 
213  //Loop over basis sites
214  for(nb = 0; nb < basis.size(); nb++) {
215 
216  tclust.clear();
217  //Make point cluster for each site
218  tclust.push_back(basis[nb]);
219  tclust.within();
220 
221  //Check if that point is among the asymmetric points already found
222  for(no = 0; no < size(); no++) {
223  if(at(no).contains(tclust, tol)) {
224  break;
225  }
226  }
227 
228 
229  //If it is not found, no is equal to asym_unit.size()
230  //add this new point cluster as a point orbit to asym_unit
231  //and get symmetrically equivalent points to fill orbit
232  if(no >= size()) {
233  push_back(GenericOrbit<ClustType >(tclust));
234  back().get_equivalent(factor_group, tol);
235  }
236  }
237  for(no = 0; no < size(); no++) {
238  at(no).collect_basis_info(basis);
239  }
240 
241  //std::cout << "finish generate_asymmeric_unit()" << std::endl;
242  return;
243  }
244 
245 
246  //*******************************
247  // Extracts the orbits that include cluster 'pivot', such that each orbit is a 'flower' of clusters
248  // with 'pivot' at the center
249 
250  template<typename ClustType>
251  bool GenericOrbitBranch<ClustType>::extract_orbits_including(const ClustType &pivot, GenericOrbitBranch<ClustType> &flowerbranch, double tol) const {
252  Index no, ne;
253  ClustType tclust(pivot.home());
254  bool found_any = false;
255 
256  for(no = 0; no < size(); no++) {
257  GenericOrbit<ClustType> torbit(tclust); //TODO check constructor
258  torbit.set_index(orbit(no).get_index());
259  for(ne = 0; ne < size(no); ne++) {
260  //std::cout << "(no,ne) = " << no << ", " << ne << '\n';
261  tclust = equiv(no, ne);
262  int tmaps(0);
263  //Repeatedly try to map the clusters onto the subcluster until it fails. In the process,
264  //map_onto_sublcuster applies the transformation to the clusters, yielding new translational
265  //clusters that we want.
266  while(tclust.map_onto_subcluster(pivot, tmaps)) {
267  tmaps++;
268  //turn off periodicity, so Orbit::contains preserves locality of pivot
269  PERIODICITY_MODE temp_mode(LOCAL);
270  if(!torbit.contains(tclust, tol)) {
271  if(torbit.size() == 0) {
272  torbit.prototype = tclust;
273  }
274  torbit.push_back(tclust);
275 
276  //We use get_equivalent, because it is efficient, and because it produces equivalence_map
277  //flowerbranch.back().get_equivalent(pivot.clust_group);
278  found_any = true;
279  }
280  }
281  }
282  if(torbit.size() != 0) {
283  flowerbranch.push_back(torbit);
284  }
285  }
286  return found_any;
287  }
288 
289 
290  //********************************************************************
291 
292  template<typename ClustType>
294  // std::cout<<"In GenericOrbitBranch<ClustType>::to_json"<<std::endl;
295  json.put_obj();
296 
297  // template<typename ClustType>
298  // class GenericOrbitBranch : public Array< GenericOrbit<ClustType> >
299  json["orbits"].put_array(size());
300  for(Index i = 0; i < size(); i++) {
301  json["orbits"][i] = at(i);
302  }
303 
304  // int m_num_sites;
305  json["m_num_sites"] = m_num_sites;
306 
307  // ClustType pivot;
308  json["pivot"] = pivot;
309 
310  // Array<int> index;
311  json["index"] = index;
312 
313  return json;
314  }
315 
316  //********************************************************************
317 
319  template<typename ClustType>
321  try {
322 
323  // template<typename ClustType>
324  // class GenericOrbitBranch : public Array< GenericOrbit<ClustType> >
325  //std::cout<<"Number of Orbits:"<<json["orbits"].size()<<std::endl;
326  GenericOrbit<ClustType> orbit(pivot);
327  this->resize(json["orbits"].size(), orbit);
328  for(int i = 0; i < json["orbits"].size(); i++) {
329  //std::cout<<"Working on orbit:"<<i<<std::endl;
330  CASM::from_json(at(i), json["orbits"][i]);
331  }
332 
333  //std::cout<<"Reading in m_num_sites"<<std::endl;
334  // int m_num_sites;
335  CASM::from_json(m_num_sites, json["m_num_sites"]);
336 
337  //std::cout<<"Reading in pivot"<<std::endl;
338  // ClustType pivot;
339  CASM::from_json(pivot, json["pivot"]);
340 
341  //std::cout<<"Reading in index"<<std::endl;
342  // Array<int> index;
343  CASM::from_json(index, json["index"]);
344 
345 
346  }
347  catch(...) {
349  throw;
350  }
351  }
352 
353 }
354 
size_type size() const
Returns array size if *this is a JSON array, object size if *this is a JSON object, 1 otherwise.
Definition: jsonParser.cc:430
ClustType prototype
Definition: Orbit.hh:47
const ClustType & equiv(Index no, Index ne) const
Method to access equivalent clusters of Orbit 'no'.
Index find(const ClustType &test_clust, double tol) const
void sort()
Sorts all of the orbits in OrbitBranch by max_length.
void from_json(ClexDescription &desc, const jsonParser &json)
void push_back(const ClustType &toPush)
bool contains(const ClustType &test_clust, double tol) const
If cluster exists in current OrbitBranch, return true.
bool contains(const ClustType &test_clust, double tol) const
Definition: Orbit_impl.hh:124
void set_pivot(const ClustType &new_pivot)
GenericOrbit< ClustType > & orbit(Index no)
Method to access orbits.
Main CASM namespace.
Definition: complete.cpp:8
const double TOL
jsonParser & to_json(jsonParser &json) const
void push_back(const GenericOrbit< ClustType > &new_orbit)
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:33
double tol
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
void print(std::ostream &stream, COORD_TYPE mode=FRAC)
EigenIndex Index
For long integer indexing:
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
void from_json(const jsonParser &json)
Assumes the pivot lattice is already set.
ClustType & prototype(Index no)
Method to access prototypes.
void set_lattice(const Lattice &new_lat, COORD_TYPE mode)
Calls set_lattice on all orbits of OrbitBranch.
jsonParser & put_obj()
Puts new empty JSON object.
Definition: jsonParser.hh:276
void set_index(Index ind) const
Definition: Orbit.hh:126
GenericOrbitBranch & apply_sym(const SymOp &op)
apply_sym to everything in this OrbitBranch (i.e, pivot and all Orbits)
bool extract_orbits_including(const ClustType &pivot, GenericOrbitBranch &flowerbranch, double tol) const
void generate_asymmetric_unit(const Array< typename ClustType::WhichCoordType > &basis, const SymGroup &factor_group, double tol)
Basic std::vector like container (deprecated)
jsonParser & put_array()
Puts new empty JSON array.
Definition: jsonParser.hh:285