CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
CanonicalSettings.hh
Go to the documentation of this file.
1 #ifndef CASM_CanonicalSettings
2 #define CASM_CanonicalSettings
3 
5 #include "casm/external/boost.hh"
6 
7 namespace CASM {
8  namespace Monte {
9 
10  class CanonicalConditions;
11 
13 
14  public:
15 
18 
20  CanonicalSettings(const PrimClex &primclex, const fs::path &read_path);
21 
22 
23  // --- CanonicalConditions settings ---------------------
24 
27 
30 
33 
35  std::vector<CanonicalConditions> custom_conditions() const;
36 
37 
38  // --- Project settings ---------------------
39 
42 
43 
44  // --- Sampler settings ---------------------
45 
47  template<typename SamplerInsertIterator>
48  SamplerInsertIterator samplers(const PrimClex &primclex, SamplerInsertIterator result) const;
49 
51  bool all_correlations() const;
52 
53 
54  private:
55 
57 
58  CanonicalConditions _conditions(std::string name) const;
59  CanonicalConditions _conditions(const jsonParser &json) const;
60 
61  template<typename jsonParserIteratorType>
62  std::tuple<bool, double> _get_precision(jsonParserIteratorType it) const;
63 
64  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
65  SamplerInsertIterator _make_all_correlations_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
66 
67  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
68  SamplerInsertIterator _make_non_zero_eci_correlations_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
69 
70  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
71  SamplerInsertIterator _make_query_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const;
72 
73  };
74 
75 
81  template<typename SamplerInsertIterator>
82  SamplerInsertIterator CanonicalSettings::samplers(
83  const PrimClex &primclex,
84  SamplerInsertIterator result) const {
85 
86  size_type data_maxlength = max_data_length();
87  std::string prop_name;
88  std::string print_name;
89  bool must_converge;
90  double prec;
91  MonteSampler *ptr;
92 
93  // copy so we can add required measurements
94  std::string level1 = "data";
95  std::string level2 = "measurements";
96  jsonParser t_measurements = (*this)[level1][level2];
97 
98  // find existing measurements
99  std::set<std::string> input_measurements;
100  for(auto it = t_measurements.cbegin(); it != t_measurements.cend(); it++) {
101  input_measurements.insert((*it)["quantity"].get<std::string>());
102  }
103 
104  std::vector<std::string> required = {
105  "potential_energy",
106  "formation_energy"
107  };
108 
109  // add required if not already requested
110  for(auto it = required.begin(); it != required.end(); ++it) {
111  if(std::find(input_measurements.begin(), input_measurements.end(), *it) == input_measurements.end()) {
112  jsonParser json;
113  json["quantity"] = *it;
114  t_measurements.push_back(json);
115  }
116  }
117 
118 
119 
120  try {
121 
122  for(auto it = t_measurements.cbegin(); it != t_measurements.cend(); it++) {
123 
124  prop_name = (*it)["quantity"].get<std::string>();
125 
126  // scalar quantities that we incrementally update
127  std::vector<std::string> scalar_possible = {
128  "formation_energy",
129  "potential_energy"
130  };
131 
132  // check if property found is in list of possible scalar properties
133  if(std::find(scalar_possible.cbegin(), scalar_possible.cend(), prop_name) != scalar_possible.cend()) {
134 
135  std::tie(must_converge, prec) = _get_precision(it);
136 
137  // if 'must converge'
138  if(must_converge) {
139  ptr = new ScalarMonteSampler(prop_name, prop_name, prec, confidence(), data_maxlength);
140  }
141  else {
142  ptr = new ScalarMonteSampler(prop_name, prop_name, confidence(), data_maxlength);
143  }
144 
145  *result++ = std::make_pair(prop_name, notstd::cloneable_ptr<MonteSampler>(ptr));
146  continue;
147  }
148 
149  // scalar quantities that we incrementally update
150  std::vector<std::string> vector_possible = {
151  "all_correlations",
152  "non_zero_eci_correlations"
153  };
154 
155  // check if property found is in list of possible vector properties
156  if(std::find(vector_possible.cbegin(), vector_possible.cend(), prop_name) != vector_possible.cend()) {
157 
158  // construct MonteSamplers for 'all_correlations'
159  if(prop_name == "all_correlations") {
160 
161  result = _make_all_correlations_samplers(primclex, it, result);
162 
163  }
164 
165  // construct MonteSamplers for 'non_zero_eci_correlations'
166  else if(prop_name == "non_zero_eci_correlations") {
167 
168  result = _make_non_zero_eci_correlations_samplers(primclex, it, result);
169 
170  }
171  continue;
172  }
173 
174  // custom query
175  _make_query_samplers(primclex, it, result);
176 
177  }
178 
179  }
180  catch(std::runtime_error &e) {
182  err_log.error<Log::standard>("'MonteSettings::samplers(const PrimClex &primclex, SamplerInsertIterator result)'");
183  err_log << "Error reading [\"" << level1 << "\"][\"" << level2 << "\"]\n" << std::endl;
184  throw;
185  }
186 
187  return result;
188  }
189 
190  template<typename jsonParserIteratorType>
191  std::tuple<bool, double> CanonicalSettings::_get_precision(jsonParserIteratorType it) const {
192  if(it->contains("precision")) {
193  return std::make_tuple(true, (*it)["precision"]. template get<double>());
194  }
195  else {
196  return std::make_tuple(false, 0.0);
197  }
198  }
199 
200  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
202  const PrimClex &primclex,
203  jsonParserIteratorType it,
204  SamplerInsertIterator result) const {
205 
206  size_type data_maxlength = max_data_length();
207  std::string prop_name;
208  std::string print_name;
209  bool must_converge;
210  double prec;
211  MonteSampler *ptr;
212 
213  for(size_type i = 0; i < primclex.clexulator(formation_energy(primclex)).corr_size(); i++) {
214 
215  prop_name = "corr";
216  print_name = std::string("corr(") + std::to_string(i) + ")";
217 
218  std::tie(must_converge, prec) = _get_precision(it);
219 
220  // if 'must converge'
221  if(must_converge) {
222  ptr = new VectorMonteSampler(prop_name, i, print_name, prec, confidence(), data_maxlength);
223  }
224  else {
225  ptr = new VectorMonteSampler(prop_name, i, print_name, confidence(), data_maxlength);
226  }
227 
228  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
229 
230  }
231 
232  return result;
233  }
234 
235  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
237  const PrimClex &primclex,
238  jsonParserIteratorType it,
239  SamplerInsertIterator result) const {
240 
241  size_type data_maxlength = max_data_length();
242  std::string prop_name;
243  std::string print_name;
244  bool must_converge;
245  double prec;
246 
247  MonteSampler *ptr;
248 
249  ECIContainer _eci = primclex.eci(formation_energy(primclex));
250 
251  for(size_type ii = 0; ii < _eci.index().size(); ii++) {
252 
253  prop_name = "corr";
254 
255  // store non-zero eci index in i
256  size_type i = _eci.index()[ii];
257 
258  print_name = std::string("corr(") + std::to_string(i) + ")";
259 
260  std::tie(must_converge, prec) = _get_precision(it);
261 
262  // if 'must converge'
263  if(must_converge) {
264  ptr = new VectorMonteSampler(prop_name, i, print_name, prec, confidence(), data_maxlength);
265  }
266  else {
267  ptr = new VectorMonteSampler(prop_name, i, print_name, confidence(), data_maxlength);
268  }
269 
270  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
271 
272  }
273 
274  return result;
275  }
276 
277  template<typename jsonParserIteratorType, typename SamplerInsertIterator>
279  const PrimClex &primclex,
280  jsonParserIteratorType it,
281  SamplerInsertIterator result) const {
282 
283  size_type data_maxlength = max_data_length();
284  double must_converge;
285  double prec;
286  std::string prop_name = (*it)["quantity"].template get<std::string>();
287  MonteSampler *ptr;
288 
289  const auto &dict = primclex.settings().query_handler<Configuration>().dict();
290 
291  typedef QueryMonteSampler::Formatter FormatterType;
292  std::shared_ptr<FormatterType> formatter = std::make_shared<FormatterType>(
293  dict.parse(prop_name));
294 
295  // make example config to test:
296  Supercell tscel(const_cast<PrimClex *>(&primclex), simulation_cell_matrix());
297  Configuration config(tscel);
298  config.init_occupation();
299  Eigen::VectorXd test = formatter->get().evaluate_as_matrix(config).row(0);
300  auto col = formatter->get().col_header(config);
301 
302  if(test.size() != col.size()) {
303  std::stringstream ss;
304  ss << "Error constructing Monte Carlo samplers from query: '" << prop_name << "'";
305  primclex.err_log() << ss.str();
306  primclex.err_log() << "headers: " << col << std::endl;
307  primclex.err_log() << " Some queries may not be available for sampling at this time." << std::endl;
308  throw std::runtime_error(ss.str());
309  }
310 
311  for(int i = 0; i < col.size(); ++i) {
312 
313  std::string print_name = col[i];
314  boost::algorithm::trim(print_name);
315 
316  std::tie(must_converge, prec) = _get_precision(it);
317 
318  // if 'must converge'
319  if(must_converge) {
320  ptr = new QueryMonteSampler(formatter, i, print_name, prec, confidence(), data_maxlength);
321  }
322  else {
323  ptr = new QueryMonteSampler(formatter, i, print_name, confidence(), data_maxlength);
324  }
325 
326  *result++ = std::make_pair(print_name, notstd::cloneable_ptr<MonteSampler>(ptr));
327 
328  }
329 
330  return result;
331 
332  }
333 
334  }
335 }
336 
337 #endif
Clexulator clexulator(const ClexDescription &key) const
Definition: PrimClex.cc:1030
CanonicalConditions _conditions(std::string name) const
CanonicalSettings()
Default constructor.
Specifies a particular cluster expansion.
void init_occupation()
Set occupant variables to background structure.
const PrimClex & primclex() const
bool all_correlations() const
Return true if all correlations should be sampled.
CanonicalConditions initial_conditions() const
Expects initial_conditions.
PrimClex * primclex
Definition: settings.cc:101
Definition: Common.hh:7
size_type max_data_length() const
Figure out how large data containers should be.
ClexDescription formation_energy(const PrimClex &primclex) const
Get formation energy cluster expansion.
Sampler for a scalar property.
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
SamplerInsertIterator samplers(const PrimClex &primclex, SamplerInsertIterator result) const
Construct MonteSamplers as specified in the MonteSettings.
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
std::vector< CanonicalConditions > custom_conditions() const
Expects custom_conditions.
T get(Args...args) const
Get data from json, using one of several alternatives.
Definition: jsonParser.hh:729
static const int standard
Definition: Log.hh:15
CanonicalConditions incremental_conditions() const
Expects incremental_conditions.
json_spirit::mObject::size_type size_type
Definition: jsonParser.hh:82
CanonicalConditions final_conditions() const
Expects final_conditions.
QueryHandler< DataObject > & query_handler()
SamplerInsertIterator _make_non_zero_eci_correlations_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
Sampler for individual elements of a vector property.
std::tuple< bool, double > _get_precision(jsonParserIteratorType it) const
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
SamplerInsertIterator _make_all_correlations_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
CompositionConverter m_comp_converter
Convert between number of species per unit cell and parametric composition.
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
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
SamplerInsertIterator _make_query_samplers(const PrimClex &primclex, jsonParserIteratorType it, SamplerInsertIterator result) const
A 'cloneable_ptr' can be used in place of 'unique_ptr'.
Definition: Log.hh:9
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.
A Configuration represents the values of all degrees of freedom in a Supercell.
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