22 const GrandCanonicalSettings &settings,
25 const GrandCanonicalSettings &settings,
26 Log &
log, GrandCanonical &mc);
45 m_site_swaps(supercell()),
47 m_all_correlations(settings.all_correlations()),
48 m_event(
primclex.composition_axes().components().size(),
49 _clexulator().corr_size()) {
61 _log() <<
"formation_energy cluster expansion: " <<
desc.name <<
"\n";
62 _log() << std::setw(16) <<
"property: " <<
desc.property <<
"\n";
63 _log() << std::setw(16) <<
"calctype: " <<
desc.calctype <<
"\n";
64 _log() << std::setw(16) <<
"ref: " <<
desc.ref <<
"\n";
65 _log() << std::setw(16) <<
"bset: " <<
desc.bset <<
"\n";
66 _log() << std::setw(16) <<
"eci: " <<
desc.eci <<
"\n";
69 _log() <<
"\nSampling: \n";
70 _log() << std::setw(24) <<
"quantity" << std::setw(24)
71 <<
"requested_precision"
74 _log() << std::setw(24) << it->first;
75 if (it->second->must_converge()) {
76 _log() << std::setw(24) << it->second->requested_precision() << std::endl;
78 _log() << std::setw(24) <<
"none" << std::endl;
81 _log() <<
"\nautomatic convergence mode?: " << std::boolalpha
101 _log() << new_conditions << std::endl << std::endl;
113 const std::string &msg) {
116 _log() << msg <<
"\n";
132 _log() << new_conditions << std::endl;
161 throw std::runtime_error(
162 "Error: Must specify motif \"configname\" or \"configdof\"");
174 const std::string &msg) {
176 _log() << new_conditions << std::endl << std::endl;
182 _log() << msg <<
"\n";
201 Index random_variable_site =
212 const std::vector<int> &possible_mutation =
215 possible_mutation[
_mtrand().randInt(possible_mutation.size() - 1)];
221 _log() <<
" Mutating site (linear index): " << mutating_site <<
"\n"
222 <<
" Mutating site (b, i, j, k): "
224 <<
" Current occupant: " << current_occupant <<
" ("
225 << site_occ[current_occupant].name() <<
")\n"
226 <<
" Proposed occupant: " << new_occupant <<
" ("
227 << site_occ[new_occupant].name() <<
")\n\n"
246 _log() <<
" components: "
248 <<
" d(N): " <<
m_event.
dN().transpose() <<
"\n"
251 <<
" param_chem_pot.transpose() * dx_dn: \n"
252 << param_chem_pot.transpose() * Mpinv <<
"\n"
253 <<
" param_chem_pot.transpose() * dx_dn * dN: "
254 << param_chem_pot.transpose() * Mpinv *
m_event.
dN().cast<
double>()
256 <<
" d(Nunit * param_chem_pot * x): "
257 << exchange_chem_pot(new_species, curr_species) <<
"\n"
260 <<
m_event.
dEf() - exchange_chem_pot(new_species, curr_species)
271 if (event.
dEpot() < 0.0) {
274 _log() <<
"Probability to accept: 1.0\n" << std::endl;
279 double rand =
_mtrand().rand53();
284 _log() <<
"Probability to accept: " << prob <<
"\n"
285 <<
"Random number: " << rand <<
"\n"
365 auto less = [&](
const double &A,
const double &B) {
return A < B - tol; };
367 std::map<double,
unsigned long, decltype(
less)> hist(
less);
377 int sublat = site_exch.
sublattice()[exch_ind];
378 int current_occupant = config_dof.
occ(mutating_site);
381 const auto &possible = site_exch.
possible_swap()[sublat][current_occupant];
382 for (
auto new_occ_it = possible.begin(); new_occ_it != possible.end();
388 double dpot_nrg = event.
dEpot();
389 if (dpot_nrg < 0.0) {
392 err_log <<
" Defect lowered the potential energy. Your motif "
394 <<
"is not the 0K ground state.\n"
396 throw std::runtime_error(
397 "Error calculating low temperature expansion. Not in the ground "
401 auto it = hist.find(dpot_nrg);
402 if (it == hist.end()) {
410 _log().
results(
"Ground state and point defect potential energy details");
415 _log() << std::setw(16) <<
"N/unitcell"
416 <<
" " << std::setw(16) <<
"dPE"
417 <<
" " << std::setw(24) <<
"N*exp(-dPE/kT)"
418 <<
" " << std::setw(16) <<
"dphi"
419 <<
" " << std::setw(16) <<
"phi" << std::endl;
424 for (
auto it = hist.rbegin(); it != hist.rend(); ++it) {
430 _log() << std::setw(16) <<
"(gs)"
433 _log() << std::setw(16) << std::setprecision(8)
436 _log() << std::setw(16) << std::setprecision(8) << it->first <<
" "
437 << std::setw(24) << std::setprecision(8)
439 << std::setw(16) << std::setprecision(8) << phi - phi_prev <<
" "
476 int sublat,
int current_occupant,
477 int new_occupant,
bool use_deltas,
478 bool all_correlations)
const {
483 if (all_correlations) {
486 nlist().sites(
nlist().unitcell_index(mutating_site)).data(),
488 current_occupant, new_occupant, event.
dCorr().data(),
492 auto end = begin +
_eci().
index().size();
495 nlist().sites(
nlist().unitcell_index(mutating_site)).data(),
497 current_occupant, new_occupant, event.
dCorr().data(),
505 if (all_correlations) {
509 nlist().sites(
nlist().unitcell_index(mutating_site)).data(),
511 before.data(),
end_ptr(before));
519 nlist().sites(
nlist().unitcell_index(mutating_site)).data(),
524 auto end = begin +
_eci().
index().size();
529 nlist().sites(
nlist().unitcell_index(mutating_site)).data(),
531 before.data(),
end_ptr(before), begin, end);
539 nlist().sites(
nlist().unitcell_index(mutating_site)).data(),
541 after.data(),
end_ptr(after), begin, end);
545 event.
dCorr() = after - before;
560 std::string colheader,
561 bool all_correlations)
const {
563 _log() << std::setw(12) <<
"i" << std::setw(16) <<
"ECI" << std::setw(16)
564 << colheader << std::endl;
566 for (
int i = 0; i <
corr.size(); ++i) {
568 bool calculated =
true;
570 if (index !=
_eci().index().size()) {
573 if (!all_correlations && index ==
_eci().index().size()) {
577 _log() << std::setw(12) << i << std::setw(16) << std::setprecision(8)
580 _log() << std::setw(16) << std::setprecision(8) <<
corr[i];
582 _log() << std::setw(16) <<
"unknown";
591 Index mutating_site,
int sublat,
592 int current_occupant,
593 int new_occupant)
const {
600 for (
int i = 0; i < event.
dN().size(); ++i) {
605 event.
set_dN(curr_species, -1);
606 event.
set_dN(new_species, 1);
610 _set_dCorr(event, mutating_site, sublat, current_occupant, new_occupant,
652 _log() <<
"Semi-grand canonical ensemble: \n"
653 <<
" Thermodynamic potential (per unitcell), phi = -kT*ln(Z)/N \n"
654 <<
" Partition function, Z = sum_i exp(-N*potential_energy_i/kT) \n"
655 <<
" composition, comp_n = origin + M * comp_x \n"
656 <<
" parametric chemical potential, param_chem_pot = M.transpose() "
658 <<
" potential_energy (per unitcell) = formation_energy - "
659 "param_chem_pot*comp_x \n\n"
665 <<
"origin: " << origin.transpose() <<
"\n"
666 <<
"comp_n: " <<
comp_n().transpose() <<
"\n"
667 <<
"comp_x: " << comp_x.transpose() <<
"\n"
668 <<
"param_chem_pot: " << param_chem_pot.transpose() <<
"\n"
669 <<
" param_chem_pot*comp_x: " << param_chem_pot.dot(comp_x) <<
"\n"
671 <<
" formation_energy - param_chem_pot*comp_x: "
681 _log() <<
"motif configname: default\n";
682 _log() <<
"using configuration with default occupation...\n" << std::endl;
693 _log() <<
"motif configname: auto\n";
694 _log() <<
"searching for minimum potential energy motif..." << std::endl;
697 auto compare = [&](
double A,
double B) {
return A < B - tol; };
699 _log() <<
"using conditions: \n";
700 _log() << cond << std::endl;
702 std::multimap<double, std::string, decltype(
compare)> configmap(
compare);
704 for (
const auto &tconfig : db) {
711 Configuration min_config = *db.find(configmap.begin()->second);
712 double min_potential_energy = configmap.begin()->first;
713 auto eq_range = configmap.equal_range(min_potential_energy);
715 if (std::distance(eq_range.first, eq_range.second) > 1) {
716 _log() <<
"Warning: Found degenerate ground states with potential energy: "
717 << std::setprecision(8) << min_potential_energy << std::endl;
718 for (
auto it = eq_range.first; it != eq_range.second; ++it) {
719 _log() <<
" " << db.find(it->second)->name() << std::endl;
721 _log() <<
"using: " << min_config.name() <<
"\n" << std::endl;
723 _log() <<
"using: " << min_config.name()
724 <<
" with potential energy: " << std::setprecision(8)
725 << min_potential_energy <<
"\n"
737 _log() <<
"motif configname: restricted_auto\n";
738 _log() <<
"searching for minimum potential energy motif..." << std::endl;
741 auto compare = [&](
double A,
double B) {
return A < B - tol; };
743 _log() <<
"using conditions: \n";
744 _log() << cond << std::endl;
746 std::multimap<double, std::string, decltype(
compare)> configmap(
compare);
748 for (
const auto &tconfig : db) {
758 auto begin = g.begin();
762 std::vector<decltype(configmap)::const_iterator> allowed;
765 auto next_it = configmap.begin();
766 while (next_it != configmap.end()) {
767 auto eq_range = configmap.equal_range(next_it->first);
770 for (
auto it = eq_range.first; it != eq_range.second; ++it) {
771 const Lattice &motif_lat = db.find(it->second)->supercell().lattice();
774 allowed.push_back(it);
779 if (allowed.size()) {
784 next_it = eq_range.second;
787 if (!allowed.size()) {
789 <<
"Found no enumerated configurations that will fill the supercell\n";
790 _log() <<
"using configuration with default occupation..." << std::endl;
795 if (allowed.size() > 1) {
796 _log() <<
"Warning: Found degenerate allowed configurations with potential "
798 << std::setprecision(8) << allowed[0]->first << std::endl;
799 for (
auto it = allowed.begin(); it != allowed.end(); ++it) {
800 _log() <<
" " << (*it)->second << std::endl;
802 _log() <<
"using: " << allowed[0]->second <<
"\n" << std::endl;
804 _log() <<
"using: " << allowed[0]->second
805 <<
" with potential energy: " << std::setprecision(8)
806 << allowed[0]->first <<
"\n"
820 _log() <<
"using configation: " <<
configname <<
"\n" << std::endl;
void calc_restricted_point_corr(ConfigDoF const &_input_configdof, long int const *_nlist_begin, long int const *_nlist_end, int neighbor_ind, double *_corr_begin, double *_corr_end, size_type const *_corr_ind_begin, size_type const *_corr_ind_end) const
Calculate select point correlations about basis site 'neighbor_ind'.
void calc_restricted_delta_point_corr(ConfigDoF const &_input_configdof, long int const *_nlist_begin, long int const *_nlist_end, int neighbor_ind, int occ_i, int occ_f, double *_corr_begin, double *_corr_end, size_type const *_corr_ind_begin, size_type const *_corr_ind_end) const
Calculate the change in select point correlations due to changing an occupant.
void calc_point_corr(ConfigDoF const &_input_configdof, long int const *_nlist_begin, long int const *_nlist_end, int neighbor_ind, double *_corr_begin, double *_corr_end) const
Calculate point correlations about basis site 'neighbor_ind'.
void calc_delta_point_corr(ConfigDoF const &_input_configdof, long int const *_nlist_begin, long int const *_nlist_end, int neighbor_ind, int occ_i, int occ_f, double *_corr_begin, double *_corr_end) const
Calculate the change in point correlations due to changing an occupant.
Eigen::VectorXd param_composition(const Eigen::VectorXd &n) const
Convert number of mol per prim, 'n' to parametric composition 'x'.
Eigen::VectorXd origin() const
The mol composition of the parameteric composition axes origin.
Eigen::MatrixXd dparam_dmol() const
Return the matrix Mij = dx_i/dn_j.
Eigen::MatrixXd dmol_dparam() const
Return the matrix Mij = dn_i/dx_j.
int & occ(Index i)
Reference occupation value on site i.
const ConfigDoF & configdof() const
const Access the DoF
static Configuration zeros(const std::shared_ptr< Supercell const > &_supercell_ptr)
ConfigInsertResult insert(bool primitive_only=false) const
Insert this configuration (in primitive & canonical form) in the database.
fs::path root_dir() const
Return casm project directory path.
const std::vector< size_type > & index() const
const Access orbit indices of ECI values
const std::vector< double > & value() const
const Access ECI values
void custom(const std::string &what)
void results(const std::string &what)
void set(const std::string &what)
void calculate(const std::string &what)
void error(const std::string &what)
void construct(const std::string &what)
static const int standard
double temperature() const
Eigen::MatrixXd exchange_chem_pot() const
matrix of exchange chemical potential, M(new, curr) = chem_pot(new)
Eigen::VectorXd param_chem_pot() const
parametric chemical potential: dg/dcomp_x
Data structure for storing information regarding a proposed grand canonical Monte Carlo event.
Eigen::VectorXd & dCorr()
Access the changes in (extensive) correlations associated with this event.
double dEf() const
Return change in (extensive) formation energy associated with this event.
void set_dEpot(double dpot_nrg)
Set change in (extensive) potential energy, dEpot = dEf - sum_i(Nunit * param_chem_pot_i * dcomp_x_i)
void set_dN(size_type species_type_index, long int dn)
Set the change in number of species in supercell. Order as in CompositionConverter::components().
void set_dEf(double dE)
Set the change in (extensive) formation energy associated with this event.
Eigen::VectorXl & dN()
Access change in number of species per supercell. Order as in CompositionConverter::components().
OccMod & occupational_change()
Access the occupational modification for this event.
double dEpot() const
Return change in (extensive) potential energy, dEpot = dEf - sum_i(Nunit * param_chem_pot_i * dcomp_x...
Clexulator const & _clexulator() const
void _update_properties()
Calculate properties given current conditions.
Eigen::VectorXd * m_comp_n
Number of atoms of each type, normalized per primitive cell.
const ECIContainer & _eci() const
const Eigen::VectorXd & corr() const
Correlations, normalized per primitive cell.
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.
void accept(const EventType &event)
Accept proposed event. Change configuration accordingly and update energies etc.
std::pair< ConfigDoF, std::string > set_state(const GrandCanonicalConditions &new_conditions, const GrandCanonicalSettings &settings)
Set configdof and conditions and clear previously collected data.
const EventType & propose()
Propose a new event, calculate delta properties, and return reference to it.
double * m_potential_energy
Potential energy, normalized per primitive cell.
void reject(const EventType &event)
Nothing needs to be done to reject a GrandCanonicalEvent.
Eigen::VectorXd & _corr()
Correlations, normalized per primitive cell.
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 lte_grand_canonical_free_energy() const
Calculate the single spin flip low temperature expansion of the grand canonical potential.
size_type steps_per_pass() const
Return number of steps per pass. Equals number of sites with variable occupation.
void _print_correlations(const Eigen::VectorXd &corr, std::string title, std::string colheader, bool all_correlations) const
Print correlations to _log()
GrandCanonical(const PrimClex &primclex, const SettingsType &settings, Log &_log)
Constructs a GrandCanonical object and prepares it for running based on Settings.
const double & formation_energy() const
Formation energy, normalized per primitive cell.
Eigen::VectorXd * m_corr
Correlations, normalized per primitive cell.
const double & potential_energy() const
Potential energy, normalized per primitive cell.
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 ...
double & _formation_energy()
Formation energy, normalized per primitive cell.
void write_results(size_type cond_index) const
Write results to files.
ConfigDoF _configname_motif(const std::string &configname) const
Generate supercell filling ConfigDoF from configuration.
const CondType & conditions() const
Return current conditions.
void set_conditions(const CondType &new_conditions)
Set conditions and clear previously collected data.
ConfigDoF _default_motif() const
Generate supercell filling ConfigDoF from default configuration.
Eigen::VectorXd & _comp_n()
Number of atoms of each type, normalized per primitive cell.
std::pair< ConfigDoF, std::string > _auto_motif(const GrandCanonicalConditions &cond) const
Generate minimum potential energy ConfigDoF.
static const ENSEMBLE ensemble
const Eigen::VectorXd & comp_n() const
Number of atoms of each type, normalized per primitive cell.
std::pair< ConfigDoF, std::string > _restricted_auto_motif(const GrandCanonicalConditions &cond) const
Generate minimum potential energy ConfigDoF for this supercell.
double * m_formation_energy
Formation energy, normalized per primitive cell.
double & _potential_energy()
Potential energy, normalized per primitive cell.
GrandCanonicalConditions m_condition
EventType m_event
Event to propose, check, accept/reject:
void set_configdof(const ConfigDoF &configdof, const std::string &msg="")
Set configdof and clear previously collected data.
bool m_use_deltas
If the supercell is large enough, calculate delta correlations directly.
const SiteExchanger m_site_swaps
Keeps track of what sites can change to what.
ClexDescription formation_energy(const PrimClex &primclex) const
Get formation energy cluster expansion.
MonteCarloEnum(const PrimClex &primclex, const MonteTypeSettings &settings, Log &log, MonteCarloType &mc)
Interface base class for all types of Monte Carlo simulations (not meant to be used polymorphically)
double & _scalar_property(std::string property_name)
Access a particular scalar property.
VectorPropertyMap & _vector_properties()
const Access vector properties map
void clear_samples()
Clear all data from all samplers.
ConfigDoF & _configdof() const
Access current microstate.
const Supercell & _supercell() const
Access the Supercell that *this is based on.
void set_nlist()
Set a pointer to the SuperNeighborList once it is ready.
const SuperNeighborList & nlist() const
const Access the SuperNeighborList via pointer stored by 'set_nlist'
ScalarPropertyMap & _scalar_properties()
Access scalar properties map.
const Supercell & supercell() const
const Access the Supercell that *this is based on
const MonteSettings & settings() const
const Access settings used for construction
void reset(const ConfigDoF &dof)
Set current microstate and clear samplers.
const Configuration & config() const
const Access current microstate
const PrimClex & primclex() const
const Access the PrimClex that *this is based on
Eigen::VectorXd & _vector_property(std::string property_name)
const Access a particular vector property
MonteCarlo(const PrimClex &primclex, const MonteTypeSettings &settings, Log &_log)
Construct with a starting ConfigDoF as specified the given MonteSettings and prepare data samplers.
const ConfigDoF & configdof() const
const Access current microstate
bool debug() const
return true if running in debug mode
const SamplerMap & samplers() const
const Access sampler map
bool must_converge() const
Return true if convergence is requested.
bool is_motif_configdof() const
Returns true if path to ConfigDoF file to use as starting motif has been specified.
std::string motif_configname() const
Configname of configuration to use as starting motif.
bool is_motif_configname() const
Returns true if configname of configuration to use as starting motif has been specified.
ConfigDoF motif_configdof(Index supercell_volume) const
ConfigDoF to use as starting motif.
fs::path motif_configdof_path() const
Path to ConfigDoF file to use as starting motif.
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.
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.
const std::vector< Index > & variable_sites() const
std::vector of indices into occupation array of ConfigDoF that have more than one allowed occupant
const std::vector< int > & sublattice() const
sublattice()[i] is the sublattice index for site variable_sites()[i]
const T & to_value() const
Returns the value the variable on the site being modified will change to.
size_type site_index() const
Returns the linear index corresponding to site in ConfigDoF.
void set(size_type _site_linear_index, size_type _sublat, const T &_to_value)
Set the values of a SiteMod.
PrimClex is the top-level data structure for a CASM project.
const std::vector< xtal::Site > & basis() const
const MasterSymGroup & factor_group() const
bool overlaps() const
Returns true if periodic images of the neighbor list overlap.
UnitCellCoord uccoord(Index linear_index) const
Return the integral coordinates corresponding to a linear index.
const Lattice & lattice() const
The super lattice.
Eigen::Matrix3l transf_mat() const
Index volume() const
Return number of primitive cells that fit inside of *this.
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Eigen::VectorXd correlations(const Configuration &config, Clexulator const &clexulator)
Returns correlations using 'clexulator'.
Eigen::VectorXd comp(const Configuration &config)
Returns parametric composition, as calculated using PrimClex::param_comp.
Eigen::VectorXd comp_n(const Configuration &config)
Returns the composition, as number of each species per unit cell.
DB::Database< T > & db() const
const DirectoryStructure & dir() const
Access DirectoryStructure object. Throw if not set.
const CompositionConverter & composition_axes() const
const Access CompositionConverter object
const PrimType & prim() const
const Access to primitive Structure
ConfigIO::GenericConfigFormatter< jsonParser > config()
ConfigIO::GenericConfigFormatter< std::string > configname()
Constructs DataFormmaterDictionary containing all Configuration DatumFormatters.
void write_observations(const MonteSettings &settings, const MonteCarlo &mc, size_type cond_index, Log &_log)
Will create (and possibly overwrite) new file with all observations from run with conditions....
void write_trajectory(const MonteSettings &settings, const MonteCarlo &mc, size_type cond_index, Log &_log)
Will create (and possibly overwrite) new file with all observations from run with conditions....
Clex make_clex(PrimClex const &primclex, CanonicalSettings const &settings)
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.
void write_conditions_json(const MonteSettings &settings, const MonteType &mc, size_type cond_index, Log &_log)
Write conditions to conditions.cond_index directory.
ENSEMBLE
Monte Carlo ensemble type.
GenericScelFormatter< double > volume()
bool less(LatticeNode const &A, LatticeNode const &B, double cost_tol)
Compare two LatticeMap objects, based on their mapping cost first, followed by PrimGrid transformatio...
std::pair< OpIterator, Eigen::Matrix3d > is_equivalent_superlattice(const Object &scel, const Object &unit, OpIterator begin, OpIterator end, double tol)
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
bool compare(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Compare ClusterInvariants.
Configuration fill_supercell(Configuration const &motif, std::shared_ptr< Supercell const > const &shared_supercell)
Index find_index(Iterator begin, Iterator end, const T &value)
Equivalent to std::distance(begin, std::find(begin, end, value))
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
T * end_ptr(std::vector< T > &container)
Return pointer one past end of vector. Equivalent to convainer.data()+container.size()
INDEX_TYPE Index
For long integer indexing:
Specifies a particular cluster expansion.
Pair of Clexulator and ECIContainer.