CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
GrandCanonicalSettings.hh
Go to the documentation of this file.
1 #ifndef CASM_GrandCanonicalSettings
2 #define CASM_GrandCanonicalSettings
3 
5 #include "casm/external/boost.hh"
6 
7 namespace CASM {
8 
9  class GrandCanonicalConditions;
10 
12 
13  public:
14 
17 
19  GrandCanonicalSettings(const PrimClex &primclex, const fs::path &read_path);
20 
21 
22  // --- GrandCanonicalConditions settings ---------------------
23 
26 
29 
32 
34  std::vector<GrandCanonicalConditions> custom_conditions() const;
35 
36 
37  // --- Project settings ---------------------
38 
41 
42 
43  // --- Sampler settings ---------------------
44 
46  template<typename SamplerInsertIterator>
47  SamplerInsertIterator samplers(const PrimClex &primclex, SamplerInsertIterator result) const;
48 
50  bool all_correlations() const;
51 
52 
53  private:
54 
55  GrandCanonicalConditions _conditions(std::string name) const;
57 
58  template<typename jsonParserIteratorType>
59  std::tuple<bool, double> _get_precision(jsonParserIteratorType it) const;
60 
61  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
62  SamplerInsertIterator _make_comp_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
63 
64  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
65  SamplerInsertIterator _make_comp_n_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
66 
67  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
68  SamplerInsertIterator _make_site_frac_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
69 
70  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
71  SamplerInsertIterator _make_atom_frac_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
72 
73  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
74  SamplerInsertIterator _make_all_correlations_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
75 
76  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
77  SamplerInsertIterator _make_non_zero_eci_correlations_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
78 
79  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
80  SamplerInsertIterator _make_query_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
81 
82  };
83 
84 
90  template<typename SamplerInsertIterator>
91  SamplerInsertIterator GrandCanonicalSettings::samplers(
92  const PrimClex &primclex,
93  SamplerInsertIterator result) const {
94 
95  if(method() == Monte::METHOD::LTE1) {//hack
96  return result;
97  }
98 
99  size_type data_maxlength = max_data_length();
100  std::string prop_name;
101  std::string print_name;
102  bool must_converge;
103  double prec;
104  MonteSampler *ptr;
105 
106  // copy so we can add required measurements
107  std::string level1 = "data";
108  std::string level2 = "measurements";
109  jsonParser t_measurements = (*this)[level1][level2];
110 
111  // find existing measurements
112  std::set<std::string> input_measurements;
113  for(auto it = t_measurements.cbegin(); it != t_measurements.cend(); it++) {
114  input_measurements.insert((*it)["quantity"].get<std::string>());
115  }
116 
117  std::vector<std::string> required = {
118  "potential_energy",
119  "formation_energy",
120  "comp",
121  "comp_n"
122  };
123 
124  // add required if not already requested
125  for(auto it = required.begin(); it != required.end(); ++it) {
126  if(std::find(input_measurements.begin(), input_measurements.end(), *it) == input_measurements.end()) {
127  jsonParser json;
128  json["quantity"] = *it;
129  t_measurements.push_back(json);
130  }
131  }
132 
133 
134 
135  try {
136 
137  for(auto it = t_measurements.cbegin(); it != t_measurements.cend(); it++) {
138 
139  prop_name = (*it)["quantity"].get<std::string>();
140 
141  // scalar quantities that we incrementally update
142  std::vector<std::string> scalar_possible = {
143  "formation_energy",
144  "potential_energy"
145  };
146 
147  // check if property found is in list of possible scalar properties
148  if(std::find(scalar_possible.cbegin(), scalar_possible.cend(), prop_name) != scalar_possible.cend()) {
149 
150  std::tie(must_converge, prec) = _get_precision(it);
151 
152  // if 'must converge'
153  if(must_converge) {
154  ptr = new ScalarMonteSampler(prop_name, prop_name, prec, confidence(), data_maxlength);
155  }
156  else {
157  ptr = new ScalarMonteSampler(prop_name, prop_name, confidence(), data_maxlength);
158  }
159 
160  *result++ = std::make_pair(prop_name, notstd::cloneable_ptr<MonteSampler>(ptr));
161  continue;
162  }
163 
164  // scalar quantities that we incrementally update
165  std::vector<std::string> vector_possible = {
166  "comp",
167  "comp_n",
168  "site_frac",
169  "atom_frac",
170  "all_correlations",
171  "non_zero_eci_correlations"
172  };
173 
174  // check if property found is in list of possible vector properties
175  if(std::find(vector_possible.cbegin(), vector_possible.cend(), prop_name) != vector_possible.cend()) {
176 
177  // construct MonteSamplers for 'comp'
178  if(prop_name == "comp") {
179 
180  result = _make_comp_samplers(primclex, it, result);
181 
182  }
183 
184  // construct MonteSamplers for 'comp_n'
185  else if(prop_name == "comp_n") {
186 
187  result = _make_comp_n_samplers(primclex, it, result);
188 
189  }
190 
191  // construct MonteSamplers for 'site_frac'
192  else if(prop_name == "site_frac") {
193 
194  result = _make_site_frac_samplers(primclex, it, result);
195 
196  }
197 
198  // construct MonteSamplers for 'atom_frac'
199  else if(prop_name == "atom_frac") {
200 
201  result = _make_atom_frac_samplers(primclex, it, result);
202 
203  }
204 
205  // construct MonteSamplers for 'all_correlations'
206  else if(prop_name == "all_correlations") {
207 
208  result = _make_all_correlations_samplers(primclex, it, result);
209 
210  }
211 
212  // construct MonteSamplers for 'non_zero_eci_correlations'
213  else if(prop_name == "non_zero_eci_correlations") {
214 
215  result = _make_non_zero_eci_correlations_samplers(primclex, it, result);
216 
217  }
218  continue;
219  }
220 
221  // custom query
222  _make_query_samplers(primclex, it, result);
223 
224  }
225 
226  }
227  catch(std::runtime_error &e) {
229  err_log.error<Log::standard>("'MonteSettings::samplers(const PrimClex &primclex, SamplerInsertIterator result)'");
230  err_log << "Error reading [\"" << level1 << "\"][\"" << level2 << "\"]\n" << std::endl;
231  throw;
232  }
233 
234  return result;
235  }
236 
237  template<typename jsonParserIteratorType>
238  std::tuple<bool, double> GrandCanonicalSettings::_get_precision(jsonParserIteratorType it) const {
239  if(it->contains("precision")) {
240  return std::make_tuple(true, (*it)["precision"]. template get<double>());
241  }
242  else {
243  return std::make_tuple(false, 0.0);
244  }
245  }
246 
247  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
249  const PrimClex &primclex,
250  jsonParserIteratorType it,
251  SamplerInsertIterator result) const {
252 
253  size_type data_maxlength = max_data_length();
254  std::string print_name;
255  bool must_converge;
256  double prec;
257  MonteSampler *ptr;
258 
259  for(size_type i = 0; i < primclex.composition_axes().independent_compositions(); i++) {
260 
261  print_name = std::string("comp(") + std::string(1, (char)(i + ((int) 'a'))) + ")";
262 
263  std::tie(must_converge, prec) = _get_precision(it);
264 
265  // if 'must converge'
266  if(must_converge) {
267  ptr = new CompMonteSampler(i, primclex.composition_axes(), print_name, prec, confidence(), data_maxlength);
268  }
269  else {
270  ptr = new CompMonteSampler(i, primclex.composition_axes(), print_name, confidence(), data_maxlength);
271  }
272 
273  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
274 
275  }
276 
277  return result;
278  }
279 
280  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
282  const PrimClex &primclex,
283  jsonParserIteratorType it,
284  SamplerInsertIterator result) const {
285 
286  size_type data_maxlength = max_data_length();
287  std::string prop_name;
288  std::string print_name;
289  bool must_converge;
290  double prec;
291  MonteSampler *ptr;
292 
293  for(size_type i = 0; i < primclex.composition_axes().components().size(); i++) {
294 
295  prop_name = "comp_n";
296 
297  print_name = std::string("comp_n(") + primclex.composition_axes().components()[i] + ")";
298 
299  std::tie(must_converge, prec) = _get_precision(it);
300 
301  // if 'must converge'
302  if(must_converge) {
303  ptr = new VectorMonteSampler(prop_name, i, print_name, prec, confidence(), data_maxlength);
304  }
305  else {
306  ptr = new VectorMonteSampler(prop_name, i, print_name, confidence(), data_maxlength);
307  }
308 
309  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
310 
311  }
312 
313  return result;
314  }
315 
316  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
318  const PrimClex &primclex,
319  jsonParserIteratorType it,
320  SamplerInsertIterator result) const {
321 
322  size_type data_maxlength = max_data_length();
323  std::string print_name;
324  bool must_converge;
325  double prec;
326  MonteSampler *ptr;
327 
328  for(size_type i = 0; i < primclex.composition_axes().components().size(); i++) {
329 
330  // SiteFracMonteSampler uses 'comp_n' to calculate 'site_frac'
331  print_name = std::string("site_frac(") + primclex.composition_axes().components()[i] + ")";
332 
333  std::tie(must_converge, prec) = _get_precision(it);
334 
335  // if 'must converge'
336  if(must_converge) {
337  ptr = new SiteFracMonteSampler(i, primclex.get_prim().basis.size(), print_name, prec, confidence(), data_maxlength);
338  }
339  else {
340  ptr = new SiteFracMonteSampler(i, primclex.get_prim().basis.size(), print_name, confidence(), data_maxlength);
341  }
342 
343  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
344 
345  }
346 
347  return result;
348  }
349 
350  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
352  const PrimClex &primclex,
353  jsonParserIteratorType it,
354  SamplerInsertIterator result) const {
355 
356  size_type data_maxlength = max_data_length();
357  std::string print_name;
358  bool must_converge;
359  double prec;
360  MonteSampler *ptr;
361 
362  // find the index for vacancies, if they are allowed,
363  // if not set to primclex.composition_axes().components().size()
364 
365  size_type vacancy_index = primclex.composition_axes().components().size();
366  for(size_type i = 0; i < primclex.composition_axes().components().size(); i++) {
367 
368  // sample for non-vacancy components
369  if(Specie(primclex.composition_axes().components()[i]).is_vacancy()) {
370  vacancy_index = i;
371  break;
372  }
373  }
374 
375 
376  for(size_type i = 0; i < primclex.composition_axes().components().size(); i++) {
377 
378  // sample for non-vacancy components
379  if(!Specie(primclex.composition_axes().components()[i]).is_vacancy()) {
380 
381  print_name = std::string("atom_frac(") + primclex.composition_axes().components()[i] + ")";
382 
383  std::tie(must_converge, prec) = _get_precision(it);
384 
385  // if 'must converge'
386  if(must_converge) {
387  ptr = new AtomFracMonteSampler(i, vacancy_index, print_name, prec, confidence(), data_maxlength);
388  }
389  else {
390  ptr = new AtomFracMonteSampler(i, vacancy_index, print_name, confidence(), data_maxlength);
391  }
392 
393  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
394 
395  }
396  }
397 
398  return result;
399  }
400 
401  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
403  const PrimClex &primclex,
404  jsonParserIteratorType it,
405  SamplerInsertIterator result) const {
406 
407  size_type data_maxlength = max_data_length();
408  std::string prop_name;
409  std::string print_name;
410  bool must_converge;
411  double prec;
412  MonteSampler *ptr;
413 
414  for(size_type i = 0; i < primclex.clexulator(formation_energy(primclex)).corr_size(); i++) {
415 
416  prop_name = "corr";
417  print_name = std::string("corr(") + std::to_string(i) + ")";
418 
419  std::tie(must_converge, prec) = _get_precision(it);
420 
421  // if 'must converge'
422  if(must_converge) {
423  ptr = new VectorMonteSampler(prop_name, i, print_name, prec, confidence(), data_maxlength);
424  }
425  else {
426  ptr = new VectorMonteSampler(prop_name, i, print_name, confidence(), data_maxlength);
427  }
428 
429  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
430 
431  }
432 
433  return result;
434  }
435 
436  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
438  const PrimClex &primclex,
439  jsonParserIteratorType it,
440  SamplerInsertIterator result) const {
441 
442  size_type data_maxlength = max_data_length();
443  std::string prop_name;
444  std::string print_name;
445  bool must_converge;
446  double prec;
447 
448  MonteSampler *ptr;
449 
450  ECIContainer _eci = primclex.eci(formation_energy(primclex));
451 
452  for(size_type ii = 0; ii < _eci.index().size(); ii++) {
453 
454  prop_name = "corr";
455 
456  // store non-zero eci index in i
457  size_type i = _eci.index()[ii];
458 
459  print_name = std::string("corr(") + std::to_string(i) + ")";
460 
461  std::tie(must_converge, prec) = _get_precision(it);
462 
463  // if 'must converge'
464  if(must_converge) {
465  ptr = new VectorMonteSampler(prop_name, i, print_name, prec, confidence(), data_maxlength);
466  }
467  else {
468  ptr = new VectorMonteSampler(prop_name, i, print_name, confidence(), data_maxlength);
469  }
470 
471  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
472 
473  }
474 
475  return result;
476  }
477 
478  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
480  const PrimClex &primclex,
481  jsonParserIteratorType it,
482  SamplerInsertIterator result) const {
483 
484  size_type data_maxlength = max_data_length();
485  double must_converge;
486  double prec;
487  std::string prop_name = (*it)["quantity"].template get<std::string>();
488  MonteSampler *ptr;
489 
490  const auto &dict = primclex.settings().query_handler<Configuration>().dict();
491 
492  typedef QueryMonteSampler::Formatter FormatterType;
493  std::shared_ptr<FormatterType> formatter = std::make_shared<FormatterType>(
494  dict.parse(prop_name));
495 
496  // make example config to test:
497  Supercell tscel(const_cast<PrimClex *>(&primclex), simulation_cell_matrix());
498  Configuration config(tscel);
499  config.init_occupation();
500  Eigen::VectorXd test = formatter->get().evaluate_as_matrix(config).row(0);
501  auto col = formatter->get().col_header(config);
502 
503  if(test.size() != col.size()) {
504  std::stringstream ss;
505  ss << "Error constructing Monte Carlo samplers from query: '" << prop_name << "'";
506  primclex.err_log() << ss.str();
507  primclex.err_log() << "headers: " << col << std::endl;
508  primclex.err_log() << " Some queries may not be available for sampling at this time." << std::endl;
509  throw std::runtime_error(ss.str());
510  }
511 
512  for(int i = 0; i < col.size(); ++i) {
513 
514  std::string print_name = col[i];
515  boost::algorithm::trim(print_name);
516 
517  std::tie(must_converge, prec) = _get_precision(it);
518 
519  // if 'must converge'
520  if(must_converge) {
521  ptr = new QueryMonteSampler(formatter, i, print_name, prec, confidence(), data_maxlength);
522  }
523  else {
524  ptr = new QueryMonteSampler(formatter, i, print_name, confidence(), data_maxlength);
525  }
526 
527  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
528 
529  }
530 
531  return result;
532 
533  }
534 
535 
536 }
537 
538 #endif
Clexulator clexulator(const ClexDescription &key) const
Definition: PrimClex.cc:1030
Sampler for atom fraction.
Specifies a particular cluster expansion.
GrandCanonicalConditions _conditions(std::string name) const
GrandCanonicalConditions incremental_conditions() const
Expects incremental_conditions.
SamplerInsertIterator _make_site_frac_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
void init_occupation()
Set occupant variables to background structure.
Index size() const
Definition: Array.hh:145
const PrimClex & primclex() const
bool is_vacancy(const std::string &name)
A vacancy is any Specie/Molecule with (name == "VA" || name == "va" || name == "Va") ...
Definition: Molecule.hh:27
PrimClex * primclex
Definition: settings.cc:101
std::tuple< bool, double > _get_precision(jsonParserIteratorType it) const
Definition: Common.hh:7
size_type max_data_length() const
Figure out how large data containers should be.
std::vector< GrandCanonicalConditions > custom_conditions() const
Expects custom_conditions.
Sampler for a scalar property.
GrandCanonicalConditions final_conditions() const
Expects final_conditions.
An abstract base class for sampling and storing data observations.
Definition: MonteSampler.hh:22
size_type corr_size() const
Number of correlations.
Definition: Clexulator.hh:370
Main CASM namespace.
Definition: complete.cpp:8
std::string to_string(ENUM val)
Return string representation of enum class.
Definition: EnumIO.hh:83
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:37
Sampler for individual elements of a vector property.
Data structure to make queries occur once each sample time.
const_iterator cend() const
Returns const_iterator to end of JSON object or JSON array.
Definition: jsonParser.cc:480
T get(Args...args) const
Get data from json, using one of several alternatives.
Definition: jsonParser.hh:729
GrandCanonicalSettings()
Default constructor.
std::vector< std::string > components() const
The order of components in mol composition vectors.
bool all_correlations() const
Return true if all correlations should be sampled.
static const int standard
Definition: Log.hh:15
json_spirit::mObject::size_type size_type
Definition: jsonParser.hh:82
QueryHandler< DataObject > & query_handler()
Sampler for individual elements of a vector property.
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
ProjectSettings & settings()
Definition: PrimClex.hh:116
Eigen::VectorXd VectorXd
const std::vector< size_type > & index() const
const Access orbit indices of ECI values
Definition: ECIContainer.hh:49
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
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:52
size_type independent_compositions() const
The dimensionality of the composition space.
const CompositionConverter & composition_axes() const
const Access CompositionConverter object
Definition: PrimClex.cc:237
SamplerInsertIterator _make_comp_n_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
ClexDescription formation_energy(const PrimClex &primclex) const
Get formation energy cluster expansion.
Sampler for parametric composition.
SamplerInsertIterator _make_query_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
SamplerInsertIterator _make_all_correlations_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
jsonParser & push_back(const T &value)
Puts new valued element at end of array of any type T for which 'jsonParser& to_json( const T &value...
Definition: jsonParser.hh:696
SamplerInsertIterator _make_atom_frac_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
GrandCanonicalConditions initial_conditions() const
Expects initial_conditions.
Monte::METHOD method() const
Return type of Monte Carlo method.
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
A 'cloneable_ptr' can be used in place of 'unique_ptr'.
Definition: Log.hh:9
SamplerInsertIterator _make_comp_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
SamplerInsertIterator samplers(const PrimClex &primclex, SamplerInsertIterator result) const
Construct MonteSamplers as specified in the MonteSettings.
Eigen::Matrix3i simulation_cell_matrix() const
Supercell matrix defining the simulation cell.
const_iterator cbegin() const
Returns const_iterator to beginning of JSON object or JSON array.
Definition: jsonParser.cc:455
double confidence() const
Given a settings jsonParser figure out the global tolerance (probably for == operator). Expects tolerance/value.
Sampler for site fraction.
SamplerInsertIterator _make_non_zero_eci_correlations_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
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
const ECIContainer & eci(const ClexDescription &key) const
Definition: PrimClex.cc:1076
Log & err_log() const
Definition: Log.hh:263
A sparse container of ECI values and their corresponding orbit indices.
Definition: ECIContainer.hh:12