CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
SiteCluster.cc
Go to the documentation of this file.
3 
4 namespace CASM {
5 
6  SiteCluster::SiteCluster(const Lattice &init_home) : GenericCluster<Site>(init_home) {
7  }
8 
9  //*************************************************
10 
11  void SiteCluster::push_back(const Site &new_site) {
13  back().set_nlist_ind(size() - 1);
14  return;
15  }
16 
17  //*************************************************
19  Array<Index> inds(size(), 0);
20  for(Index i = 0; i < size(); i++)
21  inds[i] = at(i).nlist_ind();
22 
23  return inds;
24  }
25  //*************************************************
26 
27  void SiteCluster::set_nlist_inds(const Array<Index> &new_indices) {
28  Array<Index> old_indices(size(), 0);
29 
30  for(Index i = 0; i < size(); i++) {
31  old_indices[i] = at(i).nlist_ind();
32  at(i).set_nlist_ind(new_indices[i]);
33  }
34  //std::cout << "Updating indices " << old_indices << " to " << new_indices << "\n";
35  clust_basis.set_dof_IDs(new_indices);
36  //ccd_basis.update_dof_IDs(old_indices, new_indices);
37 
38  return;
39  }
40 
41  //*************************************************
42 
44  return m_trans_nlist_inds;
45  }
46 
47  //*************************************************
48 
50  return m_trans_nlist_inds[i];
51  }
52 
53  //*************************************************
54 
55  void SiteCluster::add_trans_nlist(const Array<Index> &new_nlist) {
56  if(new_nlist.size() != size()) {
57  std::cerr << "CRITICAL ERROR: Size mismatch in SiteCluster::add_trans_nlist().\n"
58  << " Exiting...\n";
59  }
60  m_trans_nlist_inds.push_back(new_nlist);
61  }
62 
63 
64  //*************************************************
65  // @param local_args[i][j] is BasisSet for i'th DoFspace at j'th site of cluster
66  // site 0 site 1 site 2
67  // DoFType 0: displacement {x0,y0,z0} {x1, y1, z1} {x2,y2,z2}
68  // DoFType 1: configuration {pA0,pB0} {} {pA2, pB2}
69  //
70  // Step 1: Get the kroenecker product of cluster permutation with DoF symrep
71  //
72  // permutation | kronecker prod | DoF Symrep (e.g., x--y displacement)
73  // [ 0 1 ] v [cos -sin]
74  // [ 1 0 ] XkX [sin cos]
75  //
76  // [x0] [ 0 0 cos -sin ] [x0]
77  // [y0] [ 0 0 sin cos ] [y0]
78  // S * [x1] = [ cos -sin 0 0 ] [x1]
79  // [x2] [ sin cos 0 0 ] [x2]
80  //
81  // ----------------------------------------------------------------------
82  //
83  // Step 2: mix-in @param global_args to get all_argsets
84  //
85  // GLOBAL ARGS
86  //
87  // strain { e1, e2, e3, e4, e5, e6}
88  // composition { comp_a, comp_b }
89  //
90  // arg_subsets = [ {x0,y0,z0,x1,y1,z1,x2,y2,z2},
91  // {pA0,pB0,pA2,pB2},
92  // {e1,e2,e3,e4,e5,e6},
93  // {comp_a,comp_b}]
94  //
96  std::vector<BasisSet const *> const &global_args,
97  Index max_poly_order) {
98  //std::cout<<"In SiteCluster::generate_clust_basis, the size of this cluster is:"<<size()<<std::endl;
99  //std::cout<<"valid_index evaluates to:"<<valid_index(max_poly_order)<<std::endl;
100 
102  if(!valid_index(max_poly_order))
103  max_poly_order = size();
104  //std::cout<<"Max_poly_order "<<max_poly_order<<std::endl;
105 
106  Array<BasisSet const *> arg_subsets;
107  for(BasisSet const *global_ptr : global_args) {
108  if(global_ptr)
109  arg_subsets.push_back(global_ptr);
110  }
111 
112  Array<BasisSet> all_local;
113  all_local.reserve(local_args.size());
114 
115  //Loop over dof's
116  for(Index d = 0; d < local_args.size(); d++) {
117  assert(local_args[d].size() == size() && "In SiteCluster::generate_clust_basis(), local_args must have same size as cluster.");
118  // Make copies of local arguments to ensure that they are distinguishable by their DoF_IDs
119  // i.e., make copies in 'tlocal' and reset the DoF_IDs to {0,1,2,etc...}
120  std::vector<BasisSet> tlocal;
121  tlocal.reserve(local_args[d].size());
122  std::vector<BasisSet const *> site_args(size(), nullptr);
123  //Loop over sites
124  for(Index i = 0; i < local_args[d].size(); i++) {
125  if(local_args[d][i]) {
126  tlocal.push_back(*local_args[d][i]);
127  tlocal.back().set_dof_IDs(Array<Index>(1, at(i).nlist_ind()));
128  site_args[i] = &tlocal.back();
129  }
130  }
131  all_local.push_back(SiteCluster_impl::construct_clust_dof_basis(*this, site_args));
132  if(all_local.back().size())
133  arg_subsets.push_back(&(all_local.back()));
134  }
135 
136  //std::cerr << "WARNING: THIS VERSION OF CASM CANNOT PRODUCE CLUSTER FUNCTIONS!! YOU WILL HAVE NO CORRELATIONS\n";
137  // BasisSet::construct_invariant_cluster_polynomials() does the heavy lifting
138  //clust_basis.construct_invariant_cluster_polynomials(site_args, global_args, clust_group, permute_group, max_poly_order);
139  clust_basis.construct_invariant_polynomials(arg_subsets, clust_group(), max_poly_order, 1);
140  }
141 
142  //*************************************************
143  /*
144  * Using the permuation group of the cluster, we
145  * count over the allowed occupants of each site
146  * and shuffle them with every permutation. We then
147  * push back every unique decoration onto decor_map
148  * which we can later use to actually make new clusters
149  */
150  //*************************************************
151 
152  //Take decor_map out of the class definiton and have this function return
153  //an equivalent object
155  Array<Array<int> > decor_map;
156  //I start counting at 1 because I don't want to decorate with the "background" occupant
157  //just everything else
158  Array<int> init(this->size(), 1);
159  Array<int> endocc;
160 
161  for(Index i = 0; i < this->size(); i++) {
162  endocc.push_back(at(i).site_occupant().size() - 1);
163  }
164 
165  Counter<Array<int> > ornaments(init, endocc, Array<int>(this->size(), 1));
166 
167  if(decor_map.size() != 0) {
168  std::cerr << "WARNING in SiteCluster::get_decor_map" << std::endl;
169  std::cerr << "You requested populating your decor_map, but it isn't empty.";
170  std::cerr << " your current map is about to be obliterated." << std::endl;
171  decor_map.clear();
172  }
173 
174  do {
175  bool new_decoration = true;
176  for(Index i = 0; i < permute_rep().size(); i++) {
177  if(decor_map.contains((permute_rep()[i]->get_permutation())->permute(ornaments()))) {
178  new_decoration = false;
179  break;
180  }
181  }
182 
183  //If you store permuations of the unique decorations seperately,
184  //then you can just compare your new arrangemets(ornaments) to the
185  //permuted group instead of the unique group.
186  if(new_decoration) {
187  decor_map.push_back(ornaments);
188  }
189  }
190  while(++ornaments);
191 
192  return decor_map;
193  }
194 
195  //*************************************************
196  /*
197  * Using the permuation group of the cluster, we
198  * count over the allowed occupants of each site
199  * and shuffle them with every permutation. We then
200  * push back every unique decoration (and equivalents) onto decor_map
201  * which we can use later
202  */
203  //*************************************************
204 
206  //std::cout << "begin SiteCluster::get_full_decor_map()" << std::endl;
207 
208  Array< Array<int> > decor_map; //[uniq][site]
209 
210  //I start counting at 0 because I want to include all decorations (including background)
211 
212  Array<int> init(this->size(), 0);
213  Array<int> endocc;
214 
215  for(Index i = 0; i < this->size(); i++) {
216  endocc.push_back(at(i).site_occupant().size() - 1);
217  }
218 
219  Counter<Array<int> > ornaments(init, endocc, Array<int>(this->size(), 1));
220 
221  do {
222  bool new_decoration = true;
223  for(Index i = 0; i < permute_rep().size(); i++) {
224  // check if a symmetry equivalent to this arrangement has already been enumerated
225  if(decor_map.contains((permute_rep()[i]->get_permutation())->permute(ornaments()))) {
226  new_decoration = false;
227  break;
228  }
229  }
230 
231  //If you store permuations of the unique decorations seperately,
232  //then you can just compare your new arrangemets(ornaments) to the
233  //permuted group instead of the unique group.
234  if(new_decoration) {
235  decor_map.push_back(ornaments);
236  }
237  }
238  while(++ornaments);
239 
240  //std::cout << "finish SiteCluster::get_full_decor_map()" << std::endl;
241  return decor_map;
242  }
243 
244 
245 
246  //*************************************************
247  /*
248  * Given a map of how to decorate a cluster, make
249  * copies of said cluster and change occ_ind at each
250  * site accordingly.
251  * Maybe this should return an OrbitBranch? See
252  * Structure::bedazzle
253  */
254  //*************************************************
255 
257  if(dmap[0].size() != this->size()) {
258  std::cerr << "ERROR in SiteCluster::get_decorations" << std::endl;
259  std::cerr << "The provided map is for a cluster of the wrong size!" << std::endl;
260  exit(70);
261  }
262 
263  Array<SiteCluster> decorations;
264  for(Index i = 0; i < dmap.size(); i++) {
265  SiteCluster decorclust(*this);
266 
267  decorclust.decorate(dmap[i]);
268 
269  decorations.push_back(decorclust);
270  }
271  return decorations;
272  }
273 
274  //*************************************************
275 
278 
279  return *this;
280  }
281 
282  //*************************************************
283 
285  return permute(perm.perm_array());
286  }
287  //*************************************************
288 
292  return *this;
293  }
294 
295  //*************************************************
296  /*
297  * Uses basis_ind() of each site in the cluster to extract
298  * values from a given bitstring. The extracted values
299  * are then returned in a new array that has the same
300  * length as the cluster.
301  */
302  //*************************************************
303 
305  Array<int> occ_array;
306 
307  for(Index i = 0; i < size(); i++) {
308  occ_array.push_back(bitstring[at(i).basis_ind()]);
309  }
310 
311  return occ_array;
312  }
313 
314  //\John G 010413
315 
316  //*************************************************
317 
321  return *this;
322  }
323 
324  //********************************************
325  void SiteCluster::print_clust_basis(std::ostream &stream, Index begin_ind, int space, char delim, COORD_TYPE mode) const {
326  if(mode == COORD_DEFAULT)
327  mode = COORD_MODE::CHECK();
328  COORD_MODE C(mode);
329  for(Index np = 0; np < size(); np++) {
330 
331  stream << std::string(space, ' ');
332 
333  stream.setf(std::ios::showpoint, std::ios_base::fixed);
334  stream.precision(5);
335  stream.width(9);
336  at(np).print(stream);
337  stream << " basis_index: " << at(np).basis_ind() << " clust_index: " << at(np).nlist_ind() << " ";
338  if(delim)
339  stream << delim;
340  }
341  stream << "\n"
342  << " Basis Functions:\n";
343  BasisSet tbasis(clust_basis);
344  tbasis.accept(OccFuncLabeler("\\phi_%b_%f(s_%n)"));
345  for(Index i = 0; i < tbasis.size(); i++) {
346  stream << " \\Phi_" << begin_ind + i << " = " << tbasis[i]->tex_formula() << std::endl;
347  }
348  }
349 
350  //*************************************************
351 
352  SiteCluster operator*(const SymOp &LHS, const SiteCluster &RHS) {
353  return SiteCluster(RHS).apply_sym(LHS);
354  }
355 
356 
358 
359  // class SiteCluster : public GenericCluster<Site>
361 
362  //BasisSet ccd_basis;
363  //if(ccd_basis.size() > 0)
364  //json["ccd_basis"] = ccd_basis;
365 
366  // BasisSet clust_basis;
367  if(clust_basis.size() > 0)
368  json["clust_basis"] = clust_basis;
369 
370  // Array<Tensor<double> >occupation_basis_tensors;
371  //if(occupation_basis_tensors.size() > 0)
372  //json["occupation_basis_tensors"] = occupation_basis_tensors;
373 
374  // Array<double> eci_coeffs;
375  //if(eci_coeffs.size() > 0)
376  //json["eci_coeffs"] = eci_coeffs;
377 
378  return json;
379  }
380 
381  void SiteCluster::from_json(const jsonParser &json) {
382  try {
383 
384  // class SiteCluster : public GenericCluster<Site>
386 
387  // No reading BasisSet yet.
388  //
389  // //BasisSet ccd_basis;
390  // if(json.contains("ccd_basis")) {
391  // from_json(ccd_basis, json["ccd_basis"]);
392  // }
393  //
394  // // BasisSet clust_basis;
395  // if(json.contains("clust_basis")) {
396  // from_json(clust_basis, json["clust_basis"]);
397  // }
398 
399 
400  // Array<Tensor<double> >occupation_basis_tensors;
401  //if(json.contains("occupation_basis_tensors")) {
402  //CASM::from_json(occupation_basis_tensors, json["occupation_basis_tensors"]);
403  //}
404 
405  // Array<double> eci_coeffs;
406  //if(json.contains("eci_coeffs")) {
407  //CASM::from_json(eci_coeffs, json["eci_coeffs"]);
408  //}
409  }
410  catch(...) {
412  throw;
413  }
414  }
415 
416  jsonParser &to_json(const SiteCluster &clust, jsonParser &json) {
417  return clust.to_json(json);
418  }
419  void from_json(SiteCluster &clust, const jsonParser &json) {
420  try {
421  clust.from_json(json);
422  }
423  catch(...) {
425  throw;
426  }
427  }
428 
429  namespace SiteCluster_impl {
430 
431  BasisSet construct_clust_dof_basis(SiteCluster const &_clust, std::vector<BasisSet const *> const &site_dof_sets) {
432  BasisSet result;
433  result.set_dof_IDs(_clust.nlist_inds());
434  Array<SymGroupRep const *> subspace_reps;
435  for(BasisSet const *site_bset_ptr : site_dof_sets) {
436  if(site_bset_ptr) {
437  result.append(*site_bset_ptr);
438  subspace_reps.push_back(SymGroupRep::RemoteHandle(_clust.clust_group(),
439  site_bset_ptr->basis_symrep_ID()).rep_ptr());
440  }
441  else {
442  subspace_reps.push_back(SymGroupRep::RemoteHandle(_clust.clust_group(),
443  SymGroupRepID::identity(0)).rep_ptr());
444  }
445  }
447  subspace_reps).add_copy_to_master());
448  return result;
449  }
450 
451  }
452 
453 }
454 
Index size() const
Size of the associate SymGroup.
Definition: SymGroupRep.hh:224
bool contains(const T &test_elem) const
Definition: Array.hh:281
void from_json(ClexDescription &desc, const jsonParser &json)
A Counter allows looping over many incrementing variables in one loop.
Definition: Counter.hh:71
Index size() const
Definition: Array.hh:145
SiteCluster & apply_sym(const SymOp &op)
Definition: SiteCluster.cc:318
jsonParser & to_json(jsonParser &json) const
Write GenericCluster to json. Does not write lattice.
Definition: Cluster.hh:227
void push_back(const T &toPush)
Definition: Array.hh:513
void push_back(const CoordType &new_coord)
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
const Array< Index > & perm_array() const
Definition: Permutation.hh:57
const SymGroupRep::RemoteHandle & permute_rep() const
Definition: Cluster.hh:50
void generate_clust_basis(multivector< BasisSet const * >::X< 2 > const &local_args, std::vector< BasisSet const * > const &global_args, Index max_poly_order=-1)
Definition: SiteCluster.cc:95
void construct_invariant_polynomials(const Array< BasisSet const * > &tsubs, const SymGroup &head_sym_group, Index order, Index min_dof_order=1)
Definition: BasisSet.cc:425
void from_json(const jsonParser &json)
Definition: SiteCluster.cc:381
ReturnArray< Array< int > > get_full_decor_map() const
Definition: SiteCluster.cc:205
void print_clust_basis(std::ostream &stream, Index begin_ind=0, int space=18, char delim=0, COORD_TYPE mode=COORD_DEFAULT) const
Definition: SiteCluster.cc:325
Main CASM namespace.
Definition: complete.cpp:8
void push_back(const Site &new_site)
Definition: SiteCluster.cc:11
const SymGroup & clust_group() const
Definition: Cluster.hh:46
SiteCluster(const Lattice &init_home)
Definition: SiteCluster.cc:6
void from_json(const jsonParser &json)
Definition: Cluster.hh:258
Array< Array< Index > > m_trans_nlist_inds
Definition: SiteCluster.hh:64
GenericCluster & permute(const Array< Index > &perm)
permute sites of the cluster, and everything that depends on the site order
Definition: Cluster_impl.hh:55
ReturnArray< int > get_occ_array(const Array< int > &bitstring) const
Extracts bits in bitstring corresponding to the cluster and returns them as an array.
Definition: SiteCluster.cc:304
void append(const BasisSet &RHS)
Definition: BasisSet.cc:112
void clear()
Definition: Array.hh:216
void print(std::ostream &stream) const
Definition: Site.cc:379
jsonParser & to_json(jsonParser &json) const
Definition: SiteCluster.cc:357
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
Index nlist_ind() const
access m_nlist_ind
Definition: Site.cc:48
GenericCluster & apply_sym_no_trans(const SymOp &op)
apply symmetry to all points of the cluster without translation
Definition: Cluster_impl.hh:85
SiteCluster & permute(const Array< Index > &iperm)
Definition: SiteCluster.cc:276
void decorate(const Array< int > decor)
Definition: SiteCluster.hh:75
EigenIndex Index
For long integer indexing:
bool accept(const FunctionVisitor &visitor)
Definition: BasisSet.cc:202
void set_basis_symrep_ID(SymGroupRepID new_ID)
Definition: BasisSet.hh:104
const Array< Array< Index > > & trans_nlists() const
Access and assign trans_nlists.
Definition: SiteCluster.cc:43
SymGroupRep const * rep_ptr() const
Definition: SymGroupRep.hh:233
Site & at(Index ind)
Definition: Array.hh:157
SymGroupRepID add_copy_to_master() const
Adds copy of this representation its home_group.
Definition: SymGroupRep.cc:123
const Array< Index > & trans_nlist(Index i) const
Definition: SiteCluster.cc:49
void set_nlist_ind(Index)
set m_nlist_ind of Site and its DoFs
Definition: Site.cc:228
ReturnArray< SiteCluster > get_decorations(const Array< Array< int > > &dmap) const
Definition: SiteCluster.cc:256
BasisSet clust_basis
Definition: SiteCluster.hh:22
SiteCluster & apply_sym_no_trans(const SymOp &op)
Definition: SiteCluster.cc:289
Index basis_ind() const
Access basis Index.
Definition: Coordinate.hh:190
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
SymGroupRep permuted_direct_sum_rep(const SymGroupRep &permute_rep, const Array< SymGroupRep const * > &sum_reps)
BasisSet & apply_sym(const SymOp &op, int dependency_layer=1)
Definition: BasisSet.cc:868
void set_nlist_inds(const Array< Index > &new_indices)
Definition: SiteCluster.cc:27
void set_dof_IDs(const Array< Index > &new_IDs)
Definition: BasisSet.cc:304
BasisSet construct_clust_dof_basis(SiteCluster const &_clust, std::vector< BasisSet const * > const &site_dof_sets)
Definition: SiteCluster.cc:431
Site & back()
Definition: Array.hh:177
ReturnArray< Array< int > > get_decor_map() const
Definition: SiteCluster.cc:154
void add_trans_nlist(const Array< Index > &new_nlist)
Definition: SiteCluster.cc:55
ReturnArray< Index > nlist_inds() const
Easily collect the current nlist_inds of the cluster's sites.
Definition: SiteCluster.cc:18
Shortcut for multidimensional vector (std::vector< std::vector< ...)
Definition: multivector.hh:26
static SymGroupRepID identity(Index dim)
Static function to construct an ID for identity representations.
bool valid_index(Index i)
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())