13 typedef std::vector<ChemicalReferenceState>::iterator RefStateIterator;
17 RefStateIterator,
double);
18 template void ChemicalReference::set_config<RefStateIterator>(
19 const std::string &, RefStateIterator, RefStateIterator,
double);
20 template void ChemicalReference::set_supercell<RefStateIterator>(
21 const std::string &, RefStateIterator, RefStateIterator,
double);
22 template void ChemicalReference::set_global<RefStateIterator>(RefStateIterator,
37 if (vec.size() != names.size()) {
38 std::cerr <<
"Error constructing ChemicalReferenceState: Number of species "
40 std::cerr <<
" struc_molecule_name: " << names <<
"\n";
41 std::cerr <<
" n(config): " << vec << std::endl;
42 throw std::runtime_error(
43 "Error constructing ChemicalReferenceState: Number of species != "
47 for (
int i = 0; i < names.size(); ++i) {
60 "Returns a reference energy as interpolated via a composition-energy "
69 for (
int i = 0; i < ref_config.size(); ++i) {
78 for (
int i = 0; i < N.cols(); i++) {
79 N.col(i) = _N.col(i + 1) - _N.col(0);
85 auto Qr = N.transpose().fullPivHouseholderQr();
86 Qr.setThreshold(lin_alg_tol);
92 void _prune_ref_config(
const PrimClex &
primclex,
93 std::vector<std::string> &ref_config,
102 while (_rank(N, lin_alg_tol) != N.cols()) {
106 double min_dist_ref = -1;
107 for (
int i = 0; i < ref_config.size(); ++i) {
108 double tot_dist = 0.0;
109 for (
int j = 0; j < ref_config.size(); ++j) {
111 tot_dist += (_N.col(i) - _N.col(j)).
norm();
114 if (tot_dist < min_dist) {
120 ref_config.erase(ref_config.begin() + min_dist_ref);
121 _N = _species_frac_matrix(
primclex, ref_config);
122 N = _species_frac_space(_N);
150 _supercell_ref, _config_ref),
155 return notstd::make_unique<ChemicalReference>(*this->
_clone());
291 const BasicStructure &prim,
const std::vector<std::string> &struc_mol_name,
298 bool has_Va = (Va_index != struc_mol_name.size());
301 _N.row(Va_index) = Eigen::VectorXd::Zero(_N.cols());
303 for (
int i = 0; i < _N.cols(); i++) {
304 _N.col(i) /= _N.col(i).sum();
312 int r = _rank(N, tol);
315 std::cerr <<
"Error in ChemicalReference::hyperplane " << std::endl;
316 std::cerr <<
"Input space (column vectors of atom_frac):\n"
318 std::cerr <<
"Rows correspond to: " <<
jsonParser(struc_mol_name)
320 std::cerr <<
"Input space rank: " << r << std::endl;
321 throw std::runtime_error(
322 "Error in ChemicalReference::hyperplane: Too many reference states "
331 Index prim_N_mol = struc_mol_name.size();
336 Eigen::MatrixXd X = N.topRows(prim_N_mol).fullPivHouseholderQr().solve(C);
338 double relative_error = (N.topRows(prim_N_mol) * X - C).
norm() / C.norm();
340 if (relative_error > tol) {
341 std::cerr <<
"Error in ChemicalReference::hyperplane " << std::endl;
342 std::cerr <<
"Input space does not span the composition space of your prim."
345 std::cerr <<
"Input space (column vectors in atom_frac space):\n"
346 << N.topRows(prim_N_mol) << std::endl;
347 std::cerr <<
"End members:\n"
349 std::cerr <<
"Prim space (column vectors in atom_frac space):\n"
351 std::cerr <<
"Rows correspond to: " <<
jsonParser(struc_mol_name)
353 std::cerr <<
"X, prim_space = input_space*X: \n" << X << std::endl;
354 std::cerr <<
"input_space*X: \n" << N.topRows(prim_N_mol) * X << std::endl;
355 std::cerr <<
"relative_error: " << relative_error << std::endl;
356 std::cerr <<
"tol: " << tol << std::endl;
358 throw std::runtime_error(
359 "Error in ChemicalReference::hyperplane: Input space does not span "
367 relative_error = (_N.transpose() * P - E).
norm() / E.norm();
369 if (relative_error > tol) {
370 std::cerr <<
"Error in ChemicalReference::hyperplane " << std::endl;
371 std::cerr <<
"Could not solve for hyperplane reference." << std::endl;
373 std::cerr <<
"Input space (column vectors in atom_frac space), N:\n"
375 std::cerr <<
"Rows correspond to: " <<
jsonParser(struc_mol_name)
377 std::cerr <<
"Solve: _N.transpose()*P = E" << std::endl;
378 std::cerr <<
"_N.transpose():\n" << _N.transpose() << std::endl;
379 std::cerr <<
"Reference state energies, E:\n" << E << std::endl;
380 std::cerr <<
"P:\n" << P.transpose() << std::endl;
381 std::cerr <<
"relative_err: " << relative_error << std::endl;
382 std::cerr <<
"tol: " << tol << std::endl;
384 throw std::runtime_error(
385 "Error in ChemicalReference::hyperplane: Could not solve for "
386 "hyperplane reference");
390 std::cerr <<
"Error in ChemicalReference::hyperplane " << std::endl;
391 std::cerr <<
"Non-zero pure Va reference: " << P.transpose() << std::endl;
392 std::cerr <<
"Elements correspond to: " <<
jsonParser(struc_mol_name)
395 throw std::runtime_error(
396 "Error in ChemicalReference::hyperplane: Input space does not span "
400 return P.head(prim_N_mol);
406 double lin_alg_tol) {
418 for (
auto it = begin; it != end; ++it) {
419 if (!it->calc_properties().has_scalar(
"energy")) {
422 double curr_dist = (target -
comp(*it)).
norm();
425 it->size() < res->size()) ||
426 (curr_dist < close_dist)) {
428 close_dist = curr_dist;
433 std::cerr <<
"Error in auto_chemical_reference: Could not find any "
435 throw std::runtime_error(
436 "Error in auto_chemical_reference: Could not find any "
448 std::vector<std::string> ref_config;
449 ref_config.push_back(closest_calculated_config(target));
451 for (
int i = 0; i < Naxes; i++) {
455 std::string
configname = closest_calculated_config(target);
460 std::cerr <<
"Error in auto_chemical_reference: Could not find enough "
461 "calculated configurations\n";
462 throw std::runtime_error(
463 "Error in auto_chemical_reference: Could not find enough calculated "
474 _prune_ref_config(
primclex, ref_config, lin_alg_tol);
477 std::vector<ChemicalReferenceState> ref_states;
478 for (
auto it = ref_config.begin(); it != ref_config.end(); ++it) {
485 ref_states.end(), lin_alg_tol);
495 indent_incr(_indent_incr),
510 for (
int i = 0; i < plane.size(); ++i) {
513 <<
"(1): " << plane(i) <<
"\n";
524 const std::vector<ChemicalReferenceState> &ref_state_vec) {
525 for (
auto it = ref_state_vec.begin(); it != ref_state_vec.end(); ++it) {
531 double num = it->second;
536 stream << it->first <<
"(";
555 const std::pair<std::string, Eigen::VectorXd> &_pair) {
556 stream << std::string(
indent,
' ') << _pair.first <<
":\n";
568 const std::pair<std::string, std::vector<ChemicalReferenceState> > &_pair) {
569 stream << std::string(
indent,
' ') << _pair.first <<
":\n";
576 print(
"Global chemical reference:");
585 print(
"Supercell specific chemical references:");
596 (res != ref_state_end) ?
print(*res) :
print(*it);
601 print(
"Configuration specific chemical references:");
612 (res != ref_state_end) ?
print(*res) :
print(*it);
const std::map< std::string, Eigen::VectorXd > & supercell() const
const Access a map of scelname to reference for Supercell specialized references
size_type erase_supercell(const std::string &scelname)
Erase hyperplane reference specialized for a Supercell.
std::map< std::string, Eigen::VectorXd > & _supercell()
const Access a map of scelname to reference for Supercell specialized references
const BasicStructure * m_prim
static Eigen::VectorXd _calc_hyperplane(const BasicStructure &prim, const std::vector< std::string > &struc_mol_name, Eigen::MatrixXd N, Eigen::VectorXd E, double tol)
Convert a set of ChemicalReferenceState to a hyperplane, including checks.
std::vector< ChemicalReferenceState > RefStateVec
void set_config(const std::string &configname, const Eigen::VectorXd &ref)
Set hyperplane reference specialized for a Configuration.
const RefStateVec & global_ref_states() const
const Access a map of configname to RefStateVec for Supercell specialized references
void set_global(const Eigen::VectorXd &ref)
Set global hyperplane reference.
const RefStateMap & config_ref_states() const
const Access a map of configname to RefStateVec for Configuration specialized references
RefStateMap m_supercell_ref_map
RefStateVec m_global_ref_vec
static const std::string Desc
RefStateMap m_config_ref_map
const std::map< std::string, Eigen::VectorXd > & config() const
const Access a map of configname to reference for Configuration specialized references
size_type erase_config(const std::string &configname)
Erase hyperplane reference specialized for a Configuration.
void set_supercell(const std::string &scelname, const Eigen::VectorXd &ref)
Set hyperplane reference specialized for a Supercell.
const Eigen::VectorXd & global() const
const Access the global reference
std::map< std::string, Eigen::VectorXd > & _config()
const Access a map of configname to reference for Configuration specialized references
std::unique_ptr< ChemicalReference > clone() const
Clone.
ChemicalReference(const BasicStructure &prim, const Eigen::VectorXd &_global_ref, SpecializedRef _supercell_ref=SpecializedRef(), SpecializedRef _config_ref=SpecializedRef())
Constructor.
const RefStateMap & supercell_ref_states() const
const Access a map of configname to RefStateVec for Supercell specialized references
ChemicalReference * _clone() const
Clone.
const BasicStructure & prim() const
Get primitive BasicStructure.
static const std::string Name
std::map< std::string, RefStateVec > RefStateMap
Eigen::VectorXd & _global()
Access the global reference.
size_type independent_compositions() const
The dimensionality of the composition space.
std::vector< std::string > components() const
The order of components in mol composition vectors.
Returns fraction of all species that are a particular species, excluding vacancies.
Maps a Configuration to a scalar value via a hyperplane.
std::map< std::string, Eigen::VectorXd > SpecializedRef
const std::map< std::string, Eigen::VectorXd > & supercell() const
const Access a map of scelname to reference for Supercell specialized references
const Eigen::VectorXd & global() const
const Access the global reference
const std::map< std::string, Eigen::VectorXd > & config() const
const Access a map of configname to reference for Configuration specialized references
PrimClex is the top-level data structure for a CASM project.
BasicStructure specifies the lattice and atomic basis of a crystal.
Eigen::VectorXd comp(const Configuration &config)
Returns parametric composition, as calculated using PrimClex::param_comp.
Eigen::VectorXd species_frac(const Configuration &config)
Returns the composition as species fraction, with [Va] = 0.0, in the order of Structure::get_struc_mo...
Eigen::CwiseUnaryOp< decltype(Local::lround_l< typename Derived::Scalar >), const Derived > lround(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd to Eigen::MatrixXl.
Eigen::CwiseUnaryOp< decltype(Local::round_l< typename Derived::Scalar >), const Derived > round(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd.
bool is_vacancy(const std::string &name)
A vacancy is any Specie/Molecule with (name == "VA" || name == "va" || name == "Va")
DB::Database< T > & db() const
const CompositionConverter & composition_axes() const
const Access CompositionConverter object
const PrimType & prim() const
const Access to primitive Structure
std::vector< std::vector< std::string > > allowed_molecule_names(BasicStructure const &_struc)
Returns a vector with a list of allowed molecule names at each site.
std::vector< std::string > struc_molecule_name(BasicStructure const &_struc)
Returns an Array of each possible Molecule in this Structure.
std::string scelname(const Structure &prim, const Lattice &superlat)
Make supercell name name [deprecated].
T norm(const Tensor< T > &ttens)
ConfigIO::GenericConfigFormatter< double > energy_per_species()
ConfigIO::GenericConfigFormatter< jsonParser > config()
AtomFrac SpeciesFrac
In the future, AtomFrac will actually be atoms only.
ConfigIO::GenericConfigFormatter< std::string > configname()
Constructs DataFormmaterDictionary containing all Configuration DatumFormatters.
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
Eigen::MatrixXd composition_space(const ParamComposition::AllowedOccupants &_allowed_occs, double tol=1e-14)
Return the composition space of a ParamComposition::AllowedOccupants.
ChemicalReference auto_chemical_reference(const PrimClex &primclex, double lin_alg_tol)
Automatically set ChemicalReference using calculated Configurations with 'extreme' compositions.
GenericDatumFormatter< std::string, DataObject > name()
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Index find_index_if(Iterator begin, Iterator end, UnaryPredicate p)
Equivalent to std::distance(begin, std::find_if(begin, end, p))
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
Eigen::MatrixXd end_members(const ParamComposition::AllowedOccupants &_allowed_occs)
Serialize CompositionConverter to JSON.
INDEX_TYPE Index
For long integer indexing:
T max(const T &A, const T &B)
std::vector< std::string > struc_mol_name
void print(const std::string &str)
ChemicalReferencePrinter(std::ostream &_stream, const ChemicalReference &_ref, int _indent=0, int _indent_incr=2)
const ChemicalReference & ref
Stores the composition and energy in a single reference state.
std::map< std::string, double > species_num
Map of Molecule name : number of each species in reference state.
double energy_per_species
Energy in this reference state.