CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
SiteExchanger.cc
Go to the documentation of this file.
2 
3 #include "casm/clex/Supercell.hh"
4 #include "casm/clex/PrimClex.hh"
5 
6 namespace CASM {
7 
8 
9  // ---- SiteExchanger Definitions ---------------------------------
10 
11 
104 
105  //The occupants in a Configuration are ordered in blocks of basis sites.
106  int scel_volume = scel.volume();
107 
108  //int scel_basis = scel->basis_size();
109  int prim_basis = scel.get_prim().basis.size();
110  std::vector<std::string> allowed_components = scel.get_primclex().composition_axes().components();
111 
112  //Count over sites in prim basis.
113  for(Index prim_basis_site = 0; prim_basis_site < prim_basis; prim_basis_site++) {
114 
115  //If the site we're working allows multiple occupants, we're interested in filling up values for it.
116  const auto &allowed = scel.get_prim().basis[prim_basis_site].allowed_occupants();
117  std::vector<std::string> site_allowed_occ(allowed.cbegin(), allowed.cend());
118 
119  if(site_allowed_occ.size() > 1) {
120 
121  //This is the center array of possible_swap and changes with each prim_basis_site with more than one allowed occupant
122  std::vector<std::vector<int> > single_possible_swap;
123 
124  //This is a site_to_mol inner array and changes with each prim_basis_site with more than one allowed occupant
125  std::vector<int> single_site_to_mol;
126 
127  //For every current occupant we could have, we need an std::vector<int> for single_possible_swap and an int for single_site_to_mol
128  for(int possible_curr_occ = 0; possible_curr_occ < site_allowed_occ.size(); possible_curr_occ++) {
129  //This is the inner array of possible_swap and tells you all the OTHER values the current occupant could have been for the site
130  std::vector<int> swaps;
131 
132  //Loop over the same thing, and only keep different values of the current occupant as swaps that could occur
133  for(int other_curr_occ = 0; other_curr_occ < site_allowed_occ.size(); other_curr_occ++) {
134  if(possible_curr_occ != other_curr_occ) {
135  swaps.push_back(other_curr_occ);
136  }
137  }
138 
139  //At this point we have all the available swaps for one site of a given current occupant, so we save them
140  single_possible_swap.push_back(swaps);
141 
142  //For site_to_mol we want a way to translate what possible_curr_occ means in terms of allowed components at the PrimClex level
143  int mol_ind = std::find(allowed_components.cbegin(), allowed_components.cend(), site_allowed_occ[possible_curr_occ]) - allowed_components.cbegin();
144 
145  //This should never ever happen
146  if(mol_ind == allowed_components.size()) {
147  std::cerr << "ERROR in Monte::populate_occ_exchange_tables" << std::endl;
148  std::cerr << "The possible components are " << allowed_components << std::endl;
149  std::cerr << "Could not find " << allowed_components[possible_curr_occ] << " in the allowed components of the PrimClex prim." << std::endl;
150  exit(9000);
151  }
152 
153  //Save the index into allowed_components
154  single_site_to_mol.push_back(mol_ind);
155  }
156 
157  //possible_swap has blocks of identical double arrays single_possible_swap. They get pushed back the appropriate amount of times here
158  m_possible_swap.push_back(single_possible_swap);
159 
160  //site_to_mol has blocks of identical single arrays single_site_to_mol. They get pushed back the appropriate amount of times here
161  m_sublat_to_mol.push_back(single_site_to_mol);
162 
163  // This loop should happen scel_volume times and takes care of repeating values in m_variable_sites and m_sublat
164  // the appropriate amount of times. Both m_variable_sites and m_sublat have the same length on the outside: one
165  // slot for each site in the Configuration that can hold more than one occupant.
166  for(int variable_site = prim_basis_site * scel_volume; variable_site < prim_basis_site * scel_volume + scel_volume; variable_site++) {
167 
168  // variable_sites determined by the counter. Contains indexes of sites in the Configuration that allow
169  // more than one occupant
170  m_variable_sites.push_back(variable_site);
171 
172  // store the sublat index
173  m_sublat.push_back(prim_basis_site);
174 
175  }
176  }
177 
178  //Here we populate m_possible_swap and m_sublat_to_mol for sublattices that only have a single allowed occupant.
179  else {
180 
181  //In this else block, single_site_to_mol can only have a single value in the array
182  std::vector<int> single_site_to_mol;
183 
184  //The one and only allowed occupant at prim_basis_site must be
185  std::string only_site_occ = scel.get_prim().basis[prim_basis_site].allowed_occupants()[0];
186 
187  //And the corresponding index for that occupant in terms of allowed_components is
188  int mol_ind = std::find(allowed_components.cbegin(), allowed_components.cend(), only_site_occ) - allowed_components.cbegin();
189  if(mol_ind == allowed_components.size()) {
190  std::cerr << "ERROR in Monte::populate_occ_exchange_tables" << std::endl;
191  std::cerr << "The possible components are " << allowed_components << std::endl;
192  std::cerr << "Could not find " << only_site_occ << " in the allowed components of the PrimClex prim." << std::endl;
193  exit(9000);
194  }
195 
196  // No swaps are possible on this sublattice, so we push back empty std::vector<std::vector<int> >
197  std::vector<std::vector<int> > single_possible_swap;
198  m_possible_swap.push_back(single_possible_swap);
199 
200  //Put that single value we found into the array
201  single_site_to_mol.push_back(mol_ind);
202 
203  m_sublat_to_mol.push_back(single_site_to_mol);
204 
205  }
206  }
207 
208  return;
209  }
210 
211 }
212 
SiteExchanger(const Supercell &scel)
Constructor determine possible swaps in the given Supercell.
std::vector< std::vector< std::vector< int > > > m_possible_swap
For a given sublattice with a particular occupant, show what OTHER occupants it could be m_possible_s...
Index size() const
Definition: Array.hh:145
void push_back(const T &toPush)
Definition: Array.hh:513
const Structure & get_prim() const
Definition: Supercell.cc:74
Main CASM namespace.
Definition: complete.cpp:8
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:37
PrimClex & get_primclex() const
Definition: Supercell.hh:201
std::vector< std::string > components() const
The order of components in mol composition vectors.
EigenIndex Index
For long integer indexing:
Index volume() const
Return number of primitive cells that fit inside of *this.
Definition: Supercell.hh:212
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
std::vector< Index > m_variable_sites
std::vector of indices into occupation array of m_confdof that have more than one allowed occupant ...
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
const CompositionConverter & composition_axes() const
const Access CompositionConverter object
Definition: PrimClex.cc:237
std::vector< int > m_sublat
m_sublat[i] is the sublattice index for site m_variable_sites[i]
std::vector< std::vector< int > > m_sublat_to_mol
Map the integer values from the possible swaps or variable sites arrays into actual species m_sublat_...