CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
GrandCanonical.cc
Go to the documentation of this file.
1 
5 #include "casm/clex/PrimClex.hh"
7 #include "casm/clex/Norm.hh"
9 
10 namespace CASM {
11 
13 
18  MonteCarlo(primclex, settings, log),
19  m_site_swaps(supercell()),
20  m_formation_energy_clex(primclex, settings.formation_energy(primclex)),
21  m_all_correlations(settings.all_correlations()),
22  m_event(primclex.composition_axes().components().size(), _clexulator().corr_size()) {
23 
24  const auto &desc = m_formation_energy_clex.desc();
25 
26  // set the SuperNeighborList...
27  set_nlist();
28 
29  // If the simulation is big enough, use delta cluster functions;
30  // else, calculate all cluster functions
32 
33  _log().construct("Grand Canonical Monte Carlo");
34  _log() << "project: " << this->primclex().get_path() << "\n";
35  _log() << "formation_energy cluster expansion: " << desc.name << "\n";
36  _log() << std::setw(16) << "property: " << desc.property << "\n";
37  _log() << std::setw(16) << "calctype: " << desc.calctype << "\n";
38  _log() << std::setw(16) << "ref: " << desc.ref << "\n";
39  _log() << std::setw(16) << "bset: " << desc.bset << "\n";
40  _log() << std::setw(16) << "eci: " << desc.eci << "\n";
41  _log() << "supercell: \n" << supercell().get_transf_mat() << "\n";
42  _log() << "use_deltas: " << std::boolalpha << m_use_deltas << "\n";
43  _log() << "\nSampling: \n";
44  _log() << std::setw(24) << "quantity" << std::setw(24) << "requested_precision" << "\n";
45  for(auto it = samplers().begin(); it != samplers().end(); ++it) {
46  _log() << std::setw(24) << it->first;
47  if(it->second->must_converge()) {
48  _log() << std::setw(24) << it->second->requested_precision() << std::endl;
49  }
50  else {
51  _log() << std::setw(24) << "none" << std::endl;
52  }
53  }
54  _log() << "\nautomatic convergence mode?: " << std::boolalpha << must_converge() << std::endl;
55  _log() << std::endl;
56 
57  }
58 
61  return m_site_swaps.variable_sites().size();
62  }
63 
64 
67  return m_condition;
68  }
69 
70 
73  _log().set("Conditions");
74  _log() << new_conditions << std::endl << std::endl;
75 
76  m_condition = new_conditions;
77 
78  clear_samples();
80 
81  return;
82  }
83 
85  void GrandCanonical::set_configdof(const ConfigDoF &configdof, const std::string &msg) {
86  _log().set("DoF");
87  if(!msg.empty()) {
88  _log() << msg << "\n";
89  }
90  _log() << std::endl;
91 
92  reset(configdof);
94  }
95 
100  std::pair<ConfigDoF, std::string> GrandCanonical::set_state(
101  const GrandCanonicalConditions &new_conditions,
102  const GrandCanonicalSettings &settings) {
103 
104  _log().set("Conditions");
105  _log() << new_conditions << std::endl;
106 
107  m_condition = new_conditions;
108 
110  std::string configname;
111 
112  if(settings.is_motif_configname()) {
113 
114  configname = settings.motif_configname();
115 
116  if(configname == "default") {
117  configdof = _default_motif();
118  }
119  else if(configname == "auto") {
120  std::tie(configdof, configname) = _auto_motif(new_conditions);
121  }
122  else if(configname == "restricted_auto") {
123  std::tie(configdof, configname) = _restricted_auto_motif(new_conditions);
124  }
125  else {
126  configdof = _configname_motif(configname);
127  }
128 
129  }
130  else if(settings.is_motif_configdof()) {
131  _log().set("DoF");
132  _log() << "motif configdof: " << settings.motif_configdof_path() << "\n";
133  _log() << "using configdof: " << settings.motif_configdof_path() << "\n" << std::endl;
134  configdof = settings.motif_configdof();
135  configname = settings.motif_configdof_path().string();
136  }
137  else {
138  throw std::runtime_error("Error: Must specify motif \"configname\" or \"configdof\"");
139  }
140 
141  reset(configdof);
143 
144  return std::make_pair(configdof, configname);
145  }
146 
149  const ConfigDoF &configdof,
150  const std::string &msg) {
151  _log().set("Conditions");
152  _log() << new_conditions << std::endl << std::endl;
153 
154  m_condition = new_conditions;
155 
156  _log().set("DoF");
157  if(!msg.empty()) {
158  _log() << msg << "\n";
159  }
160  _log() << std::endl;
161 
162  reset(configdof);
164 
165  return;
166  }
167 
168 
175 
176  // Randomly pick a site that's allowed more than one occupant
177  Index random_variable_site = _mtrand().randInt(m_site_swaps.variable_sites().size() - 1);
178 
179  // Determine what that site's linear index is and what the sublattice index is
180  Index mutating_site = m_site_swaps.variable_sites()[random_variable_site];
181  Index sublat = m_site_swaps.sublat()[random_variable_site];
182 
183  // Determine the current occupant of the mutating site
184  int current_occupant = configdof().occ(mutating_site);
185 
186  // Randomly pick a new occupant for the mutating site
187  const std::vector<int> &possible_mutation = m_site_swaps.possible_swap()[sublat][current_occupant];
188  int new_occupant = possible_mutation[_mtrand().randInt(possible_mutation.size() - 1)];
189 
190  if(debug()) {
191  const auto &site_occ = primclex().get_prim().basis[sublat].site_occupant();
192  _log().custom("Propose event");
193 
194  _log() << " Mutating site (linear index): " << mutating_site << "\n"
195  << " Mutating site (b, i, j, k): " << supercell().uccoord(mutating_site) << "\n"
196  << " Current occupant: " << current_occupant << " (" << site_occ[current_occupant].name << ")\n"
197  << " Proposed occupant: " << new_occupant << " (" << site_occ[new_occupant].name << ")\n\n"
198 
199  << " beta: " << m_condition.beta() << "\n"
200  << " T: " << m_condition.temperature() << std::endl;
201  }
202 
203  // Update delta properties in m_event
204  _update_deltas(m_event, mutating_site, sublat, current_occupant, new_occupant);
205 
206  if(debug()) {
207 
208  auto origin = primclex().composition_axes().origin();
209  auto exchange_chem_pot = m_condition.exchange_chem_pot();
210  auto param_chem_pot = m_condition.param_chem_pot();
211  auto Mpinv = primclex().composition_axes().dparam_dmol();
212  // auto V = supercell().volume();
213  Index curr_species = m_site_swaps.sublat_to_mol()[sublat][current_occupant];
214  Index new_species = m_site_swaps.sublat_to_mol()[sublat][new_occupant];
215 
216  _log() << " components: " << jsonParser(primclex().composition_axes().components()) << "\n"
217  << " d(N): " << m_event.dN().transpose() << "\n"
218  << " dx_dn: \n" << Mpinv << "\n"
219  << " param_chem_pot.transpose() * dx_dn: \n" << param_chem_pot.transpose()*Mpinv << "\n"
220  << " param_chem_pot.transpose() * dx_dn * dN: " << param_chem_pot.transpose()*Mpinv *m_event.dN().cast<double>() << "\n"
221  << " d(Nunit * param_chem_pot * x): " << exchange_chem_pot(new_species, curr_species) << "\n"
222  << " d(Ef): " << m_event.dEf() << "\n"
223  << " d(Epot): " << m_event.dEf() - exchange_chem_pot(new_species, curr_species) << "\n"
224  << std::endl;
225 
226 
227  }
228 
229  return m_event;
230  }
231 
234 
235  if(event.dEpot() < 0.0) {
236 
237  if(debug()) {
238  _log().custom("Check event");
239  _log() << "Probability to accept: 1.0\n" << std::endl;
240  }
241  return true;
242  }
243 
244  double rand = _mtrand().rand53();
245  double prob = exp(-event.dEpot() * m_condition.beta());
246 
247  if(debug()) {
248  _log().custom("Check event");
249  _log() << "Probability to accept: " << prob << "\n"
250  << "Random number: " << rand << "\n" << std::endl;
251  }
252 
253  return rand < prob;
254  }
255 
262  void GrandCanonical::accept(const EventType &event) {
263 
264  if(debug()) {
265  _log().custom("Accept Event");
266  _log() << std::endl;
267  }
268 
269  // First apply changes to configuration (just a single occupant change)
271 
272  // Next update all properties that changed from the event
273  _formation_energy() += event.dEf() / supercell().volume();
274  _potential_energy() += event.dEpot() / supercell().volume();
275  _corr() += event.dCorr() / supercell().volume();
276  _comp_n() += event.dN().cast<double>() / supercell().volume();
277 
278  return;
279  }
280 
282  void GrandCanonical::reject(const EventType &event) {
283  if(debug()) {
284  _log().custom("Reject Event");
285  _log() << std::endl;
286  }
287  return;
288  }
289 
318 
319  const SiteExchanger &site_exch = m_site_swaps;
320  const ConfigDoF &config_dof = configdof();
322 
323  double tol = 1e-12;
324 
325  auto less = [&](const double & A, const double & B) {
326  return A < B - tol;
327  };
328 
329  std::map<double, unsigned long, decltype(less)> hist(less);
330 
331  // no defect case
332  hist[0.0] = 1;
333 
334  // double sum_exp = 0.0;
335 
336  //Loop over sites that can change occupants
337  for(Index exch_ind = 0; exch_ind < site_exch.variable_sites().size(); exch_ind++) {
338 
339  //Transform exchanger index to ConfigDoF index
340  Index mutating_site = site_exch.variable_sites()[exch_ind];
341  int sublat = site_exch.sublat()[exch_ind];
342  int current_occupant = config_dof.occ(mutating_site);
343 
344  //Loop over possible occupants for site that can change
345  const auto &possible = site_exch.possible_swap()[sublat][current_occupant];
346  for(auto new_occ_it = possible.begin(); new_occ_it != possible.end(); ++new_occ_it) {
347 
348  _update_deltas(event, mutating_site, sublat, current_occupant, *new_occ_it);
349 
350  //save the result
351  double dpot_nrg = event.dEpot();
352  if(dpot_nrg < 0.0) {
354  err_log.error<Log::standard>("Calculating low temperature expansion");
355  err_log << " Defect lowered the potential energy. Your motif configuration "
356  << "is not the 0K ground state.\n" << std::endl;
357  throw std::runtime_error("Error calculating low temperature expansion. Not in the ground state.");
358  }
359 
360 
361  auto it = hist.find(dpot_nrg);
362  if(it == hist.end()) {
363  hist[dpot_nrg] = 1;
364  }
365  else {
366  it->second++;
367  }
368  }
369  }
370 
371  _log().results("Ground state and point defect potential energy details");
372  _log() << "T: " << m_condition.temperature() << std::endl;
373  _log() << "kT: " << 1.0 / m_condition.beta() << std::endl;
374  _log() << "Beta: " << m_condition.beta() << std::endl << std::endl;
375 
376  _log() << std::setw(16) << "N/unitcell" << " "
377  << std::setw(16) << "dPE" << " "
378  << std::setw(24) << "N*exp(-dPE/kT)" << " "
379  << std::setw(16) << "dphi" << " "
380  << std::setw(16) << "phi" << std::endl;
381 
382  double tsum = 0.0;
383  double phi = 0.0;
384  double phi_prev;
385  for(auto it = hist.rbegin(); it != hist.rend(); ++it) {
386  phi_prev = phi;
387  tsum += it->second * exp(-(it->first) * m_condition.beta());
388  phi = std::log(tsum) / m_condition.beta() / supercell().volume();
389 
390  if(almost_equal(it->first, 0.0, tol)) {
391  _log() << std::setw(16) << "(gs)" << " ";
392  }
393  else {
394  _log() << std::setw(16) << std::setprecision(8) << (1.0 * it->second) / supercell().volume() << " ";
395  }
396  _log() << std::setw(16) << std::setprecision(8) << it->first << " "
397  << std::setw(24) << std::setprecision(8) << it->second *exp(-it->first * m_condition.beta()) << " "
398  << std::setw(16) << std::setprecision(8) << phi - phi_prev << " "
399  << std::setw(16) << std::setprecision(8) << potential_energy() - phi << std::endl;
400 
401  }
402 
403  _log() << "phi_LTE(1): " << std::setprecision(12) << potential_energy() - phi << std::endl << std::endl;
404 
405  return potential_energy() - phi;
406 
407  }
408 
410  void GrandCanonical::write_results(Index cond_index) const {
411  CASM::write_results(settings(), *this, _log());
412  write_conditions_json(settings(), *this, cond_index, _log());
413  write_observations(settings(), *this, cond_index, _log());
414  write_trajectory(settings(), *this, cond_index, _log());
415  //write_pos_trajectory(settings(), *this, cond_index);
416  }
417 
422  double GrandCanonical::potential_energy(const Configuration &config) const {
423  //if(&config == &this->config()) { return potential_energy(); }
424 
425  auto corr = correlations(config, _clexulator());
426  double formation_energy = _eci() * corr.data();
427  auto comp_x = primclex().composition_axes().param_composition(CASM::comp_n(config));
428  return formation_energy - comp_x.dot(m_condition.param_chem_pot());
429  }
430 
433  Index mutating_site,
434  int sublat,
435  int current_occupant,
436  int new_occupant,
437  bool use_deltas,
438  bool all_correlations) const {
439 
440  // uses _clexulator(), nlist(), _configdof()
441 
442  // Point the Clexulator to the right neighborhood and right ConfigDoF
443  _clexulator().set_config_occ(_configdof().occupation().begin());
444  _clexulator().set_nlist(nlist().sites(nlist().unitcell_index(mutating_site)).data());
445 
446  if(use_deltas) {
447 
448  // Calculate the change in correlations due to this event
449  if(all_correlations) {
451  current_occupant,
452  new_occupant,
453  event.dCorr().data());
454  }
455  else {
456  auto begin = _eci().index().data();
457  auto end = begin + _eci().index().size();
459  current_occupant,
460  new_occupant,
461  event.dCorr().data(),
462  begin,
463  end);
464  }
465  }
466  else {
467 
468  Eigen::VectorXd before { Eigen::VectorXd::Zero(event.dCorr().size()) };
469  Eigen::VectorXd after { Eigen::VectorXd::Zero(event.dCorr().size()) };
470 
471  // Calculate the change in points correlations due to this event
472  if(all_correlations) {
473 
474  // Calculate before
475  _clexulator().calc_point_corr(sublat, before.data());
476 
477  // Apply change
478  _configdof().occ(mutating_site) = new_occupant;
479 
480  // Calculate after
481  _clexulator().calc_point_corr(sublat, after.data());
482  }
483  else {
484  auto begin = _eci().index().data();
485  auto end = begin + _eci().index().size();
486 
487  // Calculate before
488  _clexulator().calc_restricted_point_corr(sublat, before.data(), begin, end);
489 
490  // Apply change
491  _configdof().occ(mutating_site) = new_occupant;
492 
493  // Calculate after
494  _clexulator().calc_restricted_point_corr(sublat, after.data(), begin, end);
495 
496  }
497 
498  // Calculate the change in correlations due to this event
499  event.dCorr() = after - before;
500 
501  // Unapply changes
502  _configdof().occ(mutating_site) = current_occupant;
503  }
504 
505  if(debug()) {
506  _print_correlations(event.dCorr(), "delta correlations", "dCorr", all_correlations);
507  }
508  }
509 
512  std::string title,
513  std::string colheader,
514  bool all_correlations) const {
515 
516  _log().calculate(title);
517  _log() << std::setw(12) << "i"
518  << std::setw(16) << "ECI"
519  << std::setw(16) << colheader
520  << std::endl;
521 
522  for(int i = 0; i < corr.size(); ++i) {
523 
524  double eci = 0.0;
525  bool calculated = true;
526  Index index = find_index(_eci().index(), i);
527  if(index != _eci().index().size()) {
528  eci = _eci().value()[index];
529  }
530  if(!all_correlations && index == _eci().index().size()) {
531  calculated = false;
532  }
533 
534  _log() << std::setw(12) << i
535  << std::setw(16) << std::setprecision(8) << eci;
536  if(calculated) {
537  _log() << std::setw(16) << std::setprecision(8) << corr[i];
538  }
539  else {
540  _log() << std::setw(16) << "unknown";
541  }
542  _log() << std::endl;
543 
544  }
545  _log() << std::endl;
546  }
547 
550  Index mutating_site,
551  int sublat,
552  int current_occupant,
553  int new_occupant) const {
554 
555  // ---- set OccMod --------------
556 
557  event.occupational_change().set(mutating_site, sublat, new_occupant);
558 
559  // ---- set dspecies --------------
560 
561  for(int i = 0; i < event.dN().size(); ++i) {
562  event.set_dN(i, 0);
563  }
564  Index curr_species = m_site_swaps.sublat_to_mol()[sublat][current_occupant];
565  Index new_species = m_site_swaps.sublat_to_mol()[sublat][new_occupant];
566  event.set_dN(curr_species, -1);
567  event.set_dN(new_species, 1);
568 
569 
570  // ---- set dcorr --------------
571 
572  _set_dCorr(event, mutating_site, sublat, current_occupant, new_occupant, m_use_deltas, m_all_correlations);
573 
574  // ---- set dformation_energy --------------
575 
576  event.set_dEf(_eci() * event.dCorr().data());
577 
578 
579  // ---- set dpotential_energy --------------
580 
581  event.set_dEpot(event.dEf() - m_condition.exchange_chem_pot(new_species, curr_species));
582 
583  }
584 
587 
588  // initialize properties and store pointers to the data strucures
590  m_corr = &_vector_property("corr");
591 
593  m_comp_n = &_vector_property("comp_n");
594 
595  _scalar_properties()["formation_energy"] = _eci() * corr().data();
596  m_formation_energy = &_scalar_property("formation_energy");
597 
599  m_potential_energy = &_scalar_property("potential_energy");
600 
601  if(debug()) {
602 
603  _print_correlations(corr(), "correlations", "corr", m_all_correlations);
604 
605  auto origin = primclex().composition_axes().origin();
606  auto exchange_chem_pot = m_condition.exchange_chem_pot();
607  auto param_chem_pot = m_condition.param_chem_pot();
608  auto comp_x = primclex().composition_axes().param_composition(comp_n());
609  auto M = primclex().composition_axes().dmol_dparam();
610 
611  _log().custom("Calculate properties");
612  _log() << "Semi-grand canonical ensemble: \n"
613  << " Thermodynamic potential (per unitcell), phi = -kT*ln(Z)/N \n"
614  << " Partition function, Z = sum_i exp(-N*potential_energy_i/kT) \n"
615  << " composition, comp_n = origin + M * comp_x \n"
616  << " parametric chemical potential, param_chem_pot = M.transpose() * chem_pot \n"
617  << " potential_energy (per unitcell) = formation_energy - param_chem_pot*comp_x \n\n"
618 
619  << "components: " << jsonParser(primclex().composition_axes().components()) << "\n"
620  << "M:\n" << M << "\n"
621  << "origin: " << origin.transpose() << "\n"
622  << "comp_n: " << comp_n().transpose() << "\n"
623  << "comp_x: " << comp_x.transpose() << "\n"
624  << "param_chem_pot: " << param_chem_pot.transpose() << "\n"
625  << " param_chem_pot*comp_x: " << param_chem_pot.dot(comp_x) << "\n"
626  << "formation_energy: " << formation_energy() << "\n"
627  << " formation_energy - param_chem_pot*comp_x: " << formation_energy() - param_chem_pot.dot(comp_x) << "\n"
628  << "potential_energy: " << potential_energy() << "\n" << std::endl;
629  }
630 
631  }
632 
635  _log().set("DoF");
636  _log() << "motif configname: default\n";
637  _log() << "using configuration with default occupation...\n" << std::endl;
638  return Configuration(_supercell(), jsonParser(), Array<int>(_supercell().num_sites(), 0)).configdof();
639  }
640 
644  std::pair<ConfigDoF, std::string> GrandCanonical::_auto_motif(const GrandCanonicalConditions &cond) const {
645 
646  _log().set("DoF");
647  _log() << "motif configname: auto\n";
648  _log() << "searching for minimum potential energy motif..." << std::endl;
649 
650  double tol = 1e-6;
651  auto compare = [&](double A, double B) {
652  return A < B - tol;
653  };
654 
655  _log() << "using conditions: \n";
656  _log() << cond << std::endl;
657 
658  std::multimap<double, const Configuration *, decltype(compare)> configmap(compare);
659  for(auto it = primclex().config_begin(); it != primclex().config_end(); ++it) {
660  configmap.insert(std::make_pair(_eci() * correlations(*it, _clexulator()) - cond.param_chem_pot().dot(CASM::comp(*it)), &(*it)));
661  }
662 
663  const Configuration &min_config = *(configmap.begin()->second);
664  double min_potential_energy = configmap.begin()->first;
665  auto eq_range = configmap.equal_range(min_potential_energy);
666 
667  if(std::distance(eq_range.first, eq_range.second) > 1) {
668  _log() << "Warning: Found degenerate ground states with potential energy: "
669  << std::setprecision(8) << min_potential_energy << std::endl;
670  for(auto it = eq_range.first; it != eq_range.second; ++it) {
671  _log() << " " << it->second->name() << std::endl;
672  }
673  _log() << "using: " << min_config.name() << "\n" << std::endl;
674  }
675  else {
676  _log() << "using: " << min_config.name() << " with potential energy: "
677  << std::setprecision(8) << min_potential_energy << "\n" << std::endl;
678  }
679 
680  return std::make_pair(
681  min_config.fill_supercell(_supercell(), primclex().get_prim().factor_group()).configdof(),
682  min_config.name());
683  }
684 
686  std::pair<ConfigDoF, std::string> GrandCanonical::_restricted_auto_motif(const GrandCanonicalConditions &cond) const {
687 
688  _log().set("DoF");
689  _log() << "motif configname: restricted_auto\n";
690  _log() << "searching for minimum potential energy motif..." << std::endl;
691 
692  double tol = 1e-6;
693  auto compare = [&](double A, double B) {
694  return A < B - tol;
695  };
696 
697  _log() << "using conditions: \n";
698  _log() << cond << std::endl;
699 
700  std::multimap<double, const Configuration *, decltype(compare)> configmap(compare);
701  for(auto it = primclex().config_begin(); it != primclex().config_end(); ++it) {
702  configmap.insert(std::make_pair(_eci() * correlations(*it, _clexulator()) - cond.param_chem_pot().dot(CASM::comp(*it)), &(*it)));
703  }
704 
705  // used to check if configurations can fill the monte carlo supercell
706  const Lattice &scel_lat = supercell().get_real_super_lattice();
707  const SymGroup &g = primclex().get_prim().factor_group();
708  auto begin = g.begin();
709  auto end = g.end();
710 
711  // save iterators pointing to configs that will fill the supercell
712  std::vector<decltype(configmap)::const_iterator> allowed;
713 
714  // iterate through groups of degenerate configs
715  auto next_it = configmap.begin();
716  while(next_it != configmap.end()) {
717  auto eq_range = configmap.equal_range(next_it->first);
718 
719  // save allowed configs
720  for(auto it = eq_range.first; it != eq_range.second; ++it) {
721  const Lattice &motif_lat = it->second->get_supercell().get_real_super_lattice();
722  if(is_supercell(scel_lat, motif_lat, begin, end, TOL).first != end) {
723  allowed.push_back(it);
724  }
725  }
726 
727  // if some found, break
728  if(allowed.size()) {
729  break;
730  }
731 
732  // else, continue to next group
733  next_it = eq_range.second;
734  }
735 
736  if(!allowed.size()) {
737  _log() << "Found no enumerated configurations that will fill the supercell\n";
738  _log() << "using configuration with default occupation..." << std::endl;
739  return std::make_pair(
741  "default");
742  }
743 
744  if(allowed.size() > 1) {
745  _log() << "Warning: Found degenerate allowed configurations with potential energy: "
746  << std::setprecision(8) << allowed[0]->first << std::endl;
747  for(auto it = allowed.begin(); it != allowed.end(); ++it) {
748  _log() << " " << (*it)->second->name() << std::endl;
749  }
750  _log() << "using: " << allowed[0]->second->name() << "\n" << std::endl;
751  }
752  else {
753  _log() << "using: " << allowed[0]->second->name() << " with potential energy: "
754  << std::setprecision(8) << allowed[0]->first << "\n" << std::endl;
755  }
756 
757  return std::make_pair(
758  allowed[0]->second->fill_supercell(_supercell(), g).configdof(),
759  allowed[0]->second->name());
760  }
761 
764 
765  _log().set("DoF");
766  _log() << "motif configname: " << configname << "\n";
767  _log() << "using configation: " << configname << "\n" << std::endl;
768 
769  const Configuration &config = primclex().configuration(configname);
770  const SymGroup &g = primclex().get_prim().factor_group();
771  return config.fill_supercell(_supercell(), g).configdof();
772  }
773 
774 }
Eigen::MatrixXd dparam_dmol() const
Return the matrix Mij = dx_i/dn_j.
pair_type eci
Definition: settings.cc:112
void write_results(const MonteSettings &settings, const MonteType &mc, Log &_log)
Will create new file or append to existing file results of the latest run.
ClexDescription & desc
Definition: settings.cc:104
Configuration fill_supercell(Supercell &scel, const SymOp &op) const
Fills supercell 'scel' with reoriented configuration, as if by apply(op,*this)
void clear_samples()
Clear all data from all samplers.
Definition: MonteCarlo.cc:46
OccMod & occupational_change()
Access the occupational modification for this event.
const SuperNeighborList & nlist() const
const Access the SuperNeighborList via pointer stored by 'set_nlist'
Definition: MonteCarlo.hh:83
void set_conditions(const CondType &new_conditions)
Set conditions and clear previously collected data.
int & occ(Index i)
Definition: ConfigDoF.hh:61
void write_conditions_json(const MonteSettings &settings, const MonteType &mc, Index cond_index, Log &_log)
Write conditions to conditions.cond_index directory.
Eigen::VectorXd param_chem_pot() const
parametric chemical potential: dg/dcomp_x
VectorPropertyMap & _vector_properties()
const Access vector properties map
Definition: MonteCarlo.hh:227
void results(const std::string &what)
Definition: Log.hh:56
Eigen::MatrixXd dmol_dparam() const
Return the matrix Mij = dn_i/dx_j.
Eigen::VectorXd origin() const
The mol composition of the parameteric composition axes origin.
size_type site_index() const
Returns the linear index corresponding to site in ConfigDoF.
Definition: DoFMod.hh:32
double dEf() const
Return change in (extensive) formation energy associated with this event.
Eigen::VectorXd param_composition(const Eigen::VectorXd &n) const
Convert number of mol per prim, 'n' to parametric composition 'x'.
Eigen::VectorXd & _corr()
Correlations, normalized per primitive cell.
bool compare(const T &A, const T &B, double tol)
Floating point comparison with tol, return A < B.
Definition: CASM_math.hh:89
ConfigDoF & _configdof() const
Access current microstate.
Definition: MonteCarlo.hh:204
Data structure for storing information regarding a proposed grand canonical Monte Carlo event...
const SiteExchanger m_site_swaps
Keeps track of what sites can change to what.
fs::path get_path() const
Return casm project directory path.
Definition: PrimClex.cc:202
PrimClex * primclex
Definition: settings.cc:101
const Configuration & config() const
const Access current microstate
Definition: MonteCarlo.hh:88
const Eigen::VectorXd & comp_n() const
Number of atoms of each type, normalized per primitive cell.
Correlation correlations(const ConfigDoF &configdof, const Supercell &scel, Clexulator &clexulator)
Returns correlations using 'clexulator'. Supercell needs a correctly populated neighbor list...
Definition: ConfigDoF.cc:200
const ConfigDoF & configdof() const
const Access the DoF
const ECIContainer & _eci() const
const Lattice & get_real_super_lattice() const
Definition: Supercell.hh:267
Index find_index(Iterator begin, Iterator end, const T &value)
Equivalent to std::distance(begin, std::find(begin, end, value))
Definition: algorithm.hh:16
bool check(const EventType &event)
Based on a random number, decide if the change in energy from the proposed event is low enough to be ...
ENSEMBLE
Monte Carlo ensemble type.
const ConfigDoF & configdof() const
const Access current microstate
Definition: MonteCarlo.hh:93
double * m_formation_energy
Formation energy, normalized per primitive cell.
const ClexDescription & desc() const
Definition: Clex.cc:12
void reset(const ConfigDoF &dof)
Set current microstate and clear samplers.
Definition: MonteCarlo.hh:101
EventType m_event
Event to propose, check, accept/reject:
Main CASM namespace.
Definition: complete.cpp:8
Log & log
Definition: settings.cc:105
Eigen::VectorXd comp(const Configuration &config)
Returns parametric composition, as calculated using PrimClex::param_comp.
const double TOL
void _print_correlations(const Eigen::VectorXd &corr, std::string title, std::string colheader, bool all_correlations) const
Print correlations to _log()
const std::vector< std::vector< std::vector< int > > > & possible_swap() const
For a given sublattice with a particular occupant, show what OTHER occupants it could be...
void set(const std::string &what)
Definition: Log.hh:46
void reject(const EventType &event)
Nothing needs to be done to reject a GrandCanonicalEvent.
bool m_all_correlations
If true, calculate all correlations; if false, calculate correlations with non-zero eci...
config_iterator config_end()
Configuration iterator: end.
Definition: PrimClex.cc:379
bool debug() const
return true if running in debug mode
Definition: MonteCarlo.hh:171
Eigen::MatrixXd exchange_chem_pot() const
matrix of exchange chemical potential, M(new, curr) = chem_pot(new) - chem_pot(curr) ...
Eigen::VectorXd & _comp_n()
Number of atoms of each type, normalized per primitive cell.
Eigen::VectorXd & dCorr()
Access the changes in (extensive) correlations associated with this event.
void write_results(Index cond_index) const
Write results to files.
Eigen::VectorXd * m_corr
Correlations, normalized per primitive cell.
void calc_point_corr(int b_index, double *corr_begin) const
Calculate point correlations about basis site 'b_index'.
Definition: Clexulator.hh:467
const std::vector< double > & value() const
const Access ECI values
Definition: ECIContainer.hh:44
const std::vector< int > & sublat() const
sublat()[i] is the sublattice index for site variable_sites()[i]
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:33
Eigen::VectorXd comp_n(const ConfigDoF &configdof, const Supercell &scel)
Returns comp_n, the number of each molecule per primitive cell, ordered as Structure::get_struc_molec...
Definition: ConfigDoF.cc:312
double tol
void _update_properties()
Calculate properties given current conditions.
void construct(const std::string &what)
Definition: Log.hh:36
void custom(const std::string &what)
Definition: Log.hh:96
void set_configdof(const ConfigDoF &configdof, const std::string &msg="")
Set configdof and clear previously collected data.
Log & _log() const
Definition: MonteCarlo.hh:208
double formation_energy(const Configuration &config)
Returns the formation energy, normalized per unit cell.
void set_config_occ(const int *_occ_ptr)
Set pointer to data structure containing occupation variables.
Definition: Clexulator.hh:400
const T & to_value() const
Returns the value the variable on the site being modified will change to.
Definition: DoFMod.hh:43
double lte_grand_canonical_free_energy() const
Calculate the single spin flip low temperature expansion of the grand canonical potential.
double & _formation_energy()
Formation energy, normalized per primitive cell.
bool is_motif_configname() const
Returns true if configname of configuration to use as starting motif has been specified.
std::string motif_configname() const
Configname of configuration to use as starting motif.
static const int standard
Definition: Log.hh:15
const MasterSymGroup & factor_group() const
Definition: Structure.cc:94
const double & potential_energy() const
Potential energy, normalized per primitive cell.
void set_nlist()
Set a pointer to the SuperNeighborList once it is ready.
Definition: MonteCarlo.hh:78
double & _potential_energy()
Potential energy, normalized per primitive cell.
const std::vector< Index > & variable_sites() const
std::vector of indices into occupation array of ConfigDoF that have more than one allowed occupant ...
bool is_motif_configdof() const
Returns true if path to ConfigDoF file to use as starting motif has been specified.
const Supercell & supercell() const
const Access the Supercell that *this is based on
Definition: MonteCarlo.hh:73
void write_trajectory(const MonteSettings &settings, const MonteCarlo &mc, Index cond_index, Log &_log)
Will create (and possibly overwrite) new file with all observations from run with conditions...
Definition: MonteIO.cc:269
const EventType & propose()
Propose a new event, calculate delta properties, and return reference to it.
void calc_delta_point_corr(int b_index, int occ_i, int occ_f, double *corr_begin) const
Calculate the change in point correlations due to changing an occupant.
Definition: Clexulator.hh:507
EigenIndex Index
For long integer indexing:
Index volume() const
Return number of primitive cells that fit inside of *this.
Definition: Supercell.hh:212
A container class for the different degrees of freedom a Configuration might have.
Definition: ConfigDoF.hh:27
void calculate(const std::string &what)
Definition: Log.hh:31
const Eigen::VectorXd & corr() const
Correlations, normalized per primitive cell.
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
const PrimClex & primclex() const
const Access the PrimClex that *this is based on
Definition: MonteCarlo.hh:68
std::pair< ConfigDoF, std::string > _restricted_auto_motif(const GrandCanonicalConditions &cond) const
Generate minimum potential energy ConfigDoF for this supercell.
Eigen::VectorXd & _vector_property(std::string property_name)
const Access a particular vector property
Definition: MonteCarlo.hh:232
Eigen::VectorXd VectorXd
const std::vector< size_type > & index() const
const Access orbit indices of ECI values
Definition: ECIContainer.hh:49
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:52
UnitCellCoord uccoord(Index i) const
Definition: Supercell.hh:224
void write_observations(const MonteSettings &settings, const MonteCarlo &mc, Index cond_index, Log &_log)
Will create (and possibly overwrite) new file with all observations from run with conditions...
Definition: MonteIO.cc:213
const CompositionConverter & composition_axes() const
const Access CompositionConverter object
Definition: PrimClex.cc:237
bool m_use_deltas
If the supercell is large enough, calculate delta correlations directly.
void calc_restricted_point_corr(int b_index, double *corr_begin, size_type const *ind_list_begin, size_type const *ind_list_end) const
Calculate select point correlations about basis site 'b_index'.
Definition: Clexulator.hh:487
std::string name() const
SCELV_A_B_C_D_E_F/i.
const Configuration & configuration(const std::string &configname) const
access configuration by name (of the form "scellname/[NUMBER]", e.g., ("SCEL1_1_1_1_0_0_0/0") ...
Definition: PrimClex.cc:347
T const * end() const
Definition: Array.hh:197
Clexulator & _clexulator() const
void calc_restricted_delta_point_corr(int b_index, int occ_i, int occ_f, double *corr_begin, size_type const *ind_list_begin, size_type const *ind_list_end) const
Calculate the change in select point correlations due to changing an occupant.
Definition: Clexulator.hh:529
ConfigIO::GenericConfigFormatter< std::string > configname()
Constructs DataFormmaterDictionary containing all Configuration DatumFormatters.
Definition: ConfigIO.cc:340
Eigen::VectorXd * m_comp_n
Number of atoms of each type, normalized per primitive cell.
Interface base class for all types of Monte Carlo simulations (not meant to be used polymorphically) ...
Definition: MonteCarlo.hh:32
std::pair< ConfigDoF, std::string > _auto_motif(const GrandCanonicalConditions &cond) const
Generate minimum potential energy ConfigDoF.
std::pair< ConfigDoF, std::string > set_state(const GrandCanonicalConditions &new_conditions, const GrandCanonicalSettings &settings)
Set configdof and conditions and clear previously collected data.
double dEpot() const
Return change in (extensive) potential energy, dEpot = dEf - sum_i(Nunit * param_chem_pot_i * dcomp_x...
void accept(const EventType &event)
Accept proposed event. Change configuration accordingly and update energies etc.
const double & formation_energy() const
Formation energy, normalized per primitive cell.
ConfigDoF _default_motif() const
Generate supercell filling ConfigDoF from default configuration.
ConfigDoF motif_configdof() const
ConfigDoF to use as starting motif.
const CondType & conditions() const
Return current conditions.
Supercell & _supercell() const
Access the Supercell that *this is based on.
Definition: MonteCarlo.hh:188
static const Monte::ENSEMBLE ensemble
bool overlaps() const
Returns true if periodic images of the neighbor list overlap.
bool must_converge() const
Return true if convergence is requested.
Definition: MonteCarlo.hh:139
const std::vector< std::vector< int > > & sublat_to_mol() const
Map the integer values from the possible swaps or variable sites arrays into actual species...
std::pair< bool, Eigen::MatrixXi > is_supercell(const Lattice &scel, const Lattice &unit, double tol)
Check if scel is a supercell of unitcell unit and some integer transformation matrix T...
Definition: Lattice.cc:1196
void _update_deltas(GrandCanonicalEvent &event, Index mutating_site, int sublat, int current_occupant, int new_occupant) const
Calculate delta properties for an event and update the event with those properties.
double & _scalar_property(std::string property_name)
Access a particular scalar property.
Definition: MonteCarlo.hh:222
void _set_dCorr(GrandCanonicalEvent &event, Index mutating_site, int sublat, int current_occupant, int new_occupant, bool use_deltas, bool all_correlations) const
Calculate delta correlations for an event.
Log & err_log
Definition: settings.cc:106
Log & default_err_log()
Definition: Log.hh:206
void error(const std::string &what)
Definition: Log.hh:86
T const * begin() const
Definition: Array.hh:185
void set_nlist(const long int *_nlist_ptr)
Set pointer to neighbor list.
Definition: Clexulator.hh:413
Definition: Log.hh:9
Index steps_per_pass() const
Return number of steps per pass. Equals number of sites with variable occupation. ...
MTRand & _mtrand()
Definition: MonteCarlo.hh:212
double * m_potential_energy
Potential energy, normalized per primitive cell.
const Eigen::Matrix3i & get_transf_mat() const
Definition: Supercell.hh:263
ConfigDoF _configname_motif(const std::string &configname) const
Generate supercell filling ConfigDoF from configuration.
ScalarPropertyMap & _scalar_properties()
Access scalar properties map.
Definition: MonteCarlo.hh:217
Clex m_formation_energy_clex
Holds Clexulator and ECI references.
Eigen::VectorXd correlations_vec(const ConfigDoF &configdof, const Supercell &scel, Clexulator &clexulator)
Returns correlations using 'clexulator'. Supercell needs a correctly populated neighbor list...
Definition: ConfigDoF.cc:242
const SamplerMap & samplers() const
const Access sampler map
Definition: MonteCarlo.hh:153
fs::path motif_configdof_path() const
Path to ConfigDoF file to use as starting motif.
const MonteSettings & settings() const
const Access settings used for construction
Definition: MonteCarlo.hh:63
bool almost_equal(const GenericCluster< CoordType > &LHS, const GenericCluster< CoordType > &RHS, double tol)
GrandCanonical(PrimClex &primclex, const SettingsType &settings, Log &_log)
Constructs a GrandCanonical object and prepares it for running based on MonteSettings.
GrandCanonicalConditions m_condition
Conditions (T, mu). Initially determined by m_settings, but can be changed halfway through the run...
A Configuration represents the values of all degrees of freedom in a Supercell.
const Structure & get_prim() const
const Access to primitive Structure
Definition: PrimClex.cc:260
Eigen::VectorXl & dN()
Access change in number of species per supercell. Order as in CompositionConverter::components().