CASM  1.1.0
A Clusters Approach to Statistical Mechanics
SiteExchanger.cc
Go to the documentation of this file.
2 
5 #include "casm/clex/PrimClex.hh"
6 #include "casm/clex/Supercell.hh"
8 
9 namespace CASM {
10 namespace Monte {
11 
12 // ---- SiteExchanger Definitions ---------------------------------
13 
136  // The occupants in a Configuration are ordered in blocks of basis sites.
137  int scel_volume = scel.volume();
138 
139  // int scel_basis = scel->basis_size();
140  int prim_basis = scel.prim().basis().size();
141  std::vector<std::string> allowed_components =
143 
144  // Count over sites in prim basis.
145  for (Index prim_basis_site = 0; prim_basis_site < prim_basis;
146  prim_basis_site++) {
147  // If the site we're working allows multiple occupants, we're interested in
148  // filling up values for it.
149  const auto &allowed =
150  scel.prim().basis()[prim_basis_site].allowed_occupants();
151  std::vector<std::string> site_allowed_occ(allowed.cbegin(), allowed.cend());
152 
153  if (site_allowed_occ.size() > 1) {
154  // This is the center array of possible_swap and changes with each
155  // prim_basis_site with more than one allowed occupant
156  std::vector<std::vector<int> > single_possible_swap;
157 
158  // This is a site_to_mol inner array and changes with each prim_basis_site
159  // with more than one allowed occupant
160  std::vector<int> single_site_to_mol;
161 
162  // For every current occupant we could have, we need an std::vector<int>
163  // for single_possible_swap and an int for single_site_to_mol
164  for (int possible_curr_occ = 0;
165  possible_curr_occ < site_allowed_occ.size(); possible_curr_occ++) {
166  // This is the inner array of possible_swap and tells you all the OTHER
167  // values the current occupant could have been for the site
168  std::vector<int> swaps;
169 
170  // Loop over the same thing, and only keep different values of the
171  // current occupant as swaps that could occur
172  for (int other_curr_occ = 0; other_curr_occ < site_allowed_occ.size();
173  other_curr_occ++) {
174  if (possible_curr_occ != other_curr_occ) {
175  swaps.push_back(other_curr_occ);
176  }
177  }
178 
179  // At this point we have all the available swaps for one site of a given
180  // current occupant, so we save them
181  single_possible_swap.push_back(swaps);
182 
183  // For site_to_mol we want a way to translate what possible_curr_occ
184  // means in terms of allowed components at the PrimClex level
185  int mol_ind =
186  std::find(allowed_components.cbegin(), allowed_components.cend(),
187  site_allowed_occ[possible_curr_occ]) -
188  allowed_components.cbegin();
189 
190  // This should never ever happen
191  if (mol_ind == allowed_components.size()) {
192  std::cerr << "ERROR in Monte::populate_occ_exchange_tables"
193  << std::endl;
194  std::cerr << "The possible components are " << allowed_components
195  << std::endl;
196  std::cerr << "Could not find "
197  << allowed_components[possible_curr_occ]
198  << " in the allowed components of the PrimClex prim."
199  << std::endl;
200  exit(9000);
201  }
202 
203  // Save the index into allowed_components
204  single_site_to_mol.push_back(mol_ind);
205  }
206 
207  // possible_swap has blocks of identical double arrays
208  // single_possible_swap. They get pushed back the appropriate amount of
209  // times here
210  m_possible_swap.push_back(single_possible_swap);
211 
212  // site_to_mol has blocks of identical single arrays single_site_to_mol.
213  // They get pushed back the appropriate amount of times here
214  m_sublat_to_mol.push_back(single_site_to_mol);
215 
216  // This loop should happen scel_volume times and takes care of repeating
217  // values in m_variable_sites and m_sublat the appropriate amount of
218  // times. Both m_variable_sites and m_sublat have the same length on the
219  // outside: one slot for each site in the Configuration that can hold more
220  // than one occupant.
221  for (int variable_site = prim_basis_site * scel_volume;
222  variable_site < prim_basis_site * scel_volume + scel_volume;
223  variable_site++) {
224  // variable_sites determined by the counter. Contains indexes of sites
225  // in the Configuration that allow more than one occupant
226  m_variable_sites.push_back(variable_site);
227 
228  // store the sublat index
229  m_sublat.push_back(prim_basis_site);
230  }
231  }
232 
233  // Here we populate m_possible_swap and m_sublat_to_mol for sublattices that
234  // only have a single allowed occupant.
235  else {
236  // In this else block, single_site_to_mol can only have a single value in
237  // the array
238  std::vector<int> single_site_to_mol;
239 
240  // The one and only allowed occupant at prim_basis_site must be
241  std::string only_site_occ =
242  scel.prim().basis()[prim_basis_site].allowed_occupants()[0];
243 
244  // And the corresponding index for that occupant in terms of
245  // allowed_components is
246  int mol_ind = std::find(allowed_components.cbegin(),
247  allowed_components.cend(), only_site_occ) -
248  allowed_components.cbegin();
249  if (mol_ind == allowed_components.size()) {
250  std::cerr << "ERROR in Monte::populate_occ_exchange_tables"
251  << std::endl;
252  std::cerr << "The possible components are " << allowed_components
253  << std::endl;
254  std::cerr << "Could not find " << only_site_occ
255  << " in the allowed components of the PrimClex prim."
256  << std::endl;
257  exit(9000);
258  }
259 
260  // No swaps are possible on this sublattice, so we push back empty
261  // std::vector<std::vector<int> >
262  std::vector<std::vector<int> > single_possible_swap;
263  m_possible_swap.push_back(single_possible_swap);
264 
265  // Put that single value we found into the array
266  single_site_to_mol.push_back(mol_ind);
267 
268  m_sublat_to_mol.push_back(single_site_to_mol);
269  }
270  }
271 
272  return;
273 }
274 
275 } // namespace Monte
276 } // namespace CASM
std::vector< std::string > components() const
The order of components in mol composition vectors.
std::vector< int > m_sublat
m_sublat[i] is the sublattice index for site m_variable_sites[i]
SiteExchanger(const Supercell &scel)
Constructor determine possible swaps in the given Supercell.
std::vector< Index > m_variable_sites
std::vector of indices into occupation array of m_confdof that have more than one allowed occupant
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_...
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...
const std::vector< xtal::Site > & basis() const
Definition: Structure.hh:102
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:51
const PrimClex & primclex() const
Use while transitioning Supercell to no longer need a PrimClex const *
Definition: Supercell.cc:150
Index volume() const
Return number of primitive cells that fit inside of *this.
Definition: Supercell.cc:227
const Structure & prim() const
Definition: Supercell.cc:113
const CompositionConverter & composition_axes() const
const Access CompositionConverter object
Definition: PrimClex.cc:243
Main CASM namespace.
Definition: APICommand.hh:8
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:16
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39