CASM  1.1.0
A Clusters Approach to Statistical Mechanics
MonteIO.cc
Go to the documentation of this file.
2 
3 #include <boost/filesystem.hpp>
4 #include <boost/filesystem/fstream.hpp>
5 
7 #include "casm/clex/ConfigDoF.hh"
16 #include "casm/external/gzstream/gzstream.h"
19 
20 namespace CASM {
21 
22 template class DataFormatter<Monte::MonteCarlo const *>;
23 template class DataFormatter<std::pair<Monte::MonteCarlo const *, Index> >;
24 
25 namespace Monte {
26 
28  : m_output_dir(fs::absolute(output_dir)) {}
29 
32  std::string prop_name) {
33  auto evaluator = [=](const ConstMonteCarloPtr &mc) {
34  return mc->samplers().find(prop_name)->second->mean(
35  mc->is_equilibrated().second);
36  };
37 
38  auto validator = [=](const ConstMonteCarloPtr &mc) {
39  return mc->is_equilibrated().first;
40  };
41 
42  std::string header = std::string("<") + prop_name + ">";
43 
45  header, header, evaluator, validator);
46 }
47 
50  std::string prop_name) {
51  auto evaluator = [=](const ConstMonteCarloPtr &mc) {
52  return mc->samplers().find(prop_name)->second->calculated_precision(
53  mc->is_equilibrated().second);
54  };
55 
56  auto validator = [=](const ConstMonteCarloPtr &mc) {
57  return mc->is_equilibrated().first;
58  };
59 
60  std::string header = std::string("prec(<") + prop_name + ">)";
61 
63  header, header, evaluator, validator);
64 }
65 
67  auto equil = mc->is_equilibrated();
68 
69  // cov = <X*Y> - <X>*<Y>
70  const MonteSampler &sampler1 = *(mc->samplers().find(prop_name1)->second);
71  const Eigen::VectorXd &obs1 = sampler1.data().observations();
72  const Eigen::VectorXd &X =
73  obs1.segment(equil.second, obs1.size() - equil.second);
74 
75  const MonteSampler &sampler2 = *(mc->samplers().find(prop_name2)->second);
76  const Eigen::VectorXd &obs2 = sampler2.data().observations();
77  const Eigen::VectorXd &Y =
78  obs2.segment(equil.second, obs2.size() - equil.second);
79 
80  double Xsum = 0.0;
81  double Ysum = 0.0;
82  double XYsum = 0.0;
83  size_type N = X.size();
84 
85  for (size_type i = 0; i < N; ++i) {
86  Xsum += X(i);
87  Ysum += Y(i);
88  XYsum += X(i) * Y(i);
89  }
90 
91  // return X.cwiseProduct(Y).mean() - X.mean()*Y.mean();
92  return (XYsum - Xsum * Ysum / N) / N;
93 }
94 
97  std::string prop_name1, std::string prop_name2) {
98  auto evaluator = CovEvaluator(prop_name1, prop_name2);
99 
100  auto validator = [=](const ConstMonteCarloPtr &mc) {
101  return mc->is_equilibrated().first;
102  };
103 
104  std::string header =
105  std::string("cov(") + prop_name1 + "," + prop_name2 + ")";
106 
108  header, header, evaluator, validator);
109 }
110 
115  auto evaluator = [=](const ConstMonteCarloPtr &mc) -> bool {
116  return mc->is_equilibrated().first;
117  };
118 
120  "is_equilibrated", "is_equilibrated", evaluator);
121 }
122 
126  auto evaluator = [=](const ConstMonteCarloPtr &mc) -> bool {
127  return mc->is_converged();
128  };
129 
131  "is_converged", "is_converged", evaluator);
132 }
133 
138  auto evaluator = [=](const ConstMonteCarloPtr &mc) -> unsigned long {
139  return mc->is_equilibrated().second;
140  };
141 
143  "N_equil_samples", "N_equil_samples", evaluator);
144 }
145 
149  auto evaluator = [=](const ConstMonteCarloPtr &mc) -> unsigned long {
150  return mc->sample_times().size() - mc->is_equilibrated().second;
151  };
152 
154  "N_avg_samples", "N_avg_samples", evaluator);
155 }
156 
159  std::pair<ConstMonteCarloPtr, size_type> >
161  auto evaluator = [=](const std::pair<ConstMonteCarloPtr, size_type> &obs) {
162  return obs.first->sample_times()[obs.second].first;
163  };
164 
166  std::pair<ConstMonteCarloPtr, size_type> >(
167  "Pass", "Pass", evaluator);
168 }
169 
173  auto evaluator = [=](const std::pair<ConstMonteCarloPtr, size_type> &obs) {
174  return obs.first->sample_times()[obs.second].second;
175  };
176 
178  std::pair<ConstMonteCarloPtr, size_type> >(
179  "Step", "Step", evaluator);
180 }
181 
184 MonteCarloObservationFormatter(std::string prop_name) {
185  auto evaluator = [=](const std::pair<ConstMonteCarloPtr, size_type> &obs) {
186  const MonteSampler &sampler =
187  *(obs.first->samplers().find(prop_name)->second);
188  return sampler.data().observations()(obs.second);
189  };
190 
191  return GenericDatumFormatter<double,
192  std::pair<ConstMonteCarloPtr, size_type> >(
193  prop_name, prop_name, evaluator);
194 }
195 
199  auto evaluator =
200  [=](const std::pair<ConstMonteCarloPtr, size_type> &site) -> int {
201  return site.first->trajectory()[site.second].occ(occ_index);
202  };
203 
204  std::string header = std::string("occ(") + std::to_string(occ_index) + ")";
205 
207  header, header, evaluator);
208 }
209 
225 
226  formatter.push_back(MonteCarloPassFormatter());
227  formatter.push_back(MonteCarloStepFormatter());
228  for (auto it = mc.samplers().cbegin(); it != mc.samplers().cend(); ++it) {
229  formatter.push_back(MonteCarloObservationFormatter(it->first));
230  }
231  return formatter;
232 }
233 
248  formatter.push_back(MonteCarloPassFormatter());
249  formatter.push_back(MonteCarloStepFormatter());
250 
251  // this is probably not the best way...
252  for (size_type i = 0; i < mc.configdof().occupation().size(); ++i) {
253  formatter.push_back(MonteCarloOccFormatter(i));
254  }
255  return formatter;
256 }
257 
260 void write_observations(const MonteSettings &settings, const MonteCarlo &mc,
261  size_type cond_index, Log &_log) {
262  try {
263  if (!settings.write_observations()) {
264  return;
265  }
266 
268  fs::create_directories(dir.conditions_dir(cond_index));
269  auto formatter = make_observation_formatter(mc);
270 
271  std::vector<std::pair<ConstMonteCarloPtr, size_type> > observations;
272  ConstMonteCarloPtr ptr = &mc;
273  for (size_type i = 0; i < mc.sample_times().size(); ++i) {
274  observations.push_back(std::make_pair(ptr, i));
275  }
276 
277  if (settings.write_csv()) {
278  gz::ogzstream sout(
279  (dir.observations_csv(cond_index).string() + ".gz").c_str());
280  _log << "write: "
281  << fs::path(dir.observations_csv(cond_index).string() + ".gz")
282  << "\n";
283  sout << formatter(observations.cbegin(), observations.cend());
284  sout.close();
285  }
286 
287  if (settings.write_json()) {
288  gz::ogzstream sout(
289  (dir.observations_json(cond_index).string() + ".gz").c_str());
290  _log << "write: "
291  << fs::path(dir.observations_json(cond_index).string() + ".gz")
292  << "\n";
294  formatter(observations.cbegin(), observations.cend())
295  .to_json_arrays(json);
296  sout << json;
297  sout.close();
298  }
299 
300  } catch (...) {
301  std::cerr << "ERROR writing observations." << std::endl;
302  throw;
303  }
304 }
305 
325 void write_trajectory(const MonteSettings &settings, const MonteCarlo &mc,
326  size_type cond_index, Log &_log) {
327  try {
328  if (!settings.write_trajectory()) {
329  return;
330  }
331 
333  fs::create_directories(dir.conditions_dir(cond_index));
334  auto formatter = make_trajectory_formatter(mc);
335  const Structure &prim = mc.primclex().prim();
336 
337  std::vector<std::pair<ConstMonteCarloPtr, size_type> > observations;
338  ConstMonteCarloPtr ptr = &mc;
339  for (size_type i = 0; i < mc.sample_times().size(); ++i) {
340  observations.push_back(std::make_pair(ptr, i));
341  }
342 
343  if (settings.write_csv()) {
344  gz::ogzstream sout(
345  (dir.trajectory_csv(cond_index).string() + ".gz").c_str());
346  _log << "write: "
347  << fs::path(dir.trajectory_csv(cond_index).string() + ".gz") << "\n";
348  sout << formatter(observations.cbegin(), observations.cend());
349  sout.close();
350 
351  int max_allowed = 0;
352  for (int i = 0; i < prim.basis().size(); i++) {
353  if (prim.basis()[i].allowed_occupants().size() > max_allowed) {
354  max_allowed = prim.basis()[i].allowed_occupants().size();
355  }
356  }
357 
358  // --- Write "occupation_key.csv" ------------
359  //
360  // site_index occ_index_0 occ_index_1 ...
361  // 0 Ni Al
362  // 1 Ni -
363  // ...
364  fs::ofstream keyout(dir.occupation_key_csv());
365  _log << "write: " << dir.occupation_key_csv() << "\n";
366  keyout << "site_index";
367  for (int i = 0; i < max_allowed; i++) {
368  keyout << "\tocc_index_" << i;
369  }
370  keyout << "\n";
371 
372  for (int i = 0; i < prim.basis().size(); i++) {
373  keyout << i;
374  for (int j = 0; j < max_allowed; j++) {
375  if (j < prim.basis()[i].allowed_occupants().size()) {
376  keyout << "\t" << prim.basis()[i].allowed_occupants()[j];
377  } else {
378  keyout << "\t-";
379  }
380  }
381  keyout << "\n";
382  }
383  keyout.close();
384  }
385 
386  if (settings.write_json()) {
388  json["Pass"] = jsonParser::array();
389  json["Step"] = jsonParser::array();
390  json["DoF"] = jsonParser::array();
391  for (auto it = mc.sample_times().cbegin(); it != mc.sample_times().cend();
392  ++it) {
393  json["Pass"].push_back(it->first);
394  json["Step"].push_back(it->second);
395  }
396  for (auto it = mc.trajectory().cbegin(); it != mc.trajectory().cend();
397  ++it) {
398  json["DoF"].push_back(*it);
399  }
400  gz::ogzstream sout(
401  (dir.trajectory_json(cond_index).string() + ".gz").c_str());
402  _log << "write: "
403  << fs::path(dir.trajectory_json(cond_index).string() + ".gz")
404  << "\n";
405  sout << json;
406  sout.close();
407 
408  // --- Write "occupation_key.json" ------------
409  //
410  // [["A", "B"],["A" "C"], ... ]
411 
413  for (int i = 0; i < prim.basis().size(); i++) {
414  key.push_back(prim.basis()[i].allowed_occupants());
415  }
416  key.write(dir.occupation_key_json());
417  _log << "write: " << dir.occupation_key_json() << "\n";
418  }
419 
420  } catch (...) {
421  std::cerr << "ERROR writing observations." << std::endl;
422  throw;
423  }
424 }
425 
429 void write_POSCAR_initial(const MonteCarlo &mc, size_type cond_index,
430  Log &_log) {
432  fs::create_directories(dir.trajectory_dir(cond_index));
433 
434  // read initial_state.json
435  ConfigDoF config_dof =
436  jsonParser(dir.initial_state_json(cond_index))
437  .get<ConfigDoF>(mc.supercell().prim(), mc.supercell().volume());
438 
439  if (!fs::exists(dir.initial_state_json(cond_index))) {
440  throw std::runtime_error(
441  std::string("ERROR in 'write_POSCAR_initial(const MonteCarlo &mc, "
442  "size_type cond_index)'\n") +
443  " File not found: " + dir.initial_state_json(cond_index).string());
444  }
445 
446  // write file
447  fs::ofstream sout(dir.POSCAR_initial(cond_index));
448  _log << "write: " << dir.POSCAR_initial(cond_index) << "\n";
450  p.sort();
451  p.print(sout);
452  return;
453 }
454 
458 void write_POSCAR_final(const MonteCarlo &mc, size_type cond_index, Log &_log) {
460  fs::create_directories(dir.trajectory_dir(cond_index));
461 
462  // read final_state.json
463  ConfigDoF config_dof =
464  jsonParser(dir.final_state_json(cond_index))
465  .get<ConfigDoF>(mc.supercell().prim(), mc.supercell().volume());
466 
467  if (!fs::exists(dir.final_state_json(cond_index))) {
468  throw std::runtime_error(
469  std::string("ERROR in 'write_POSCAR_final(const MonteCarlo &mc, "
470  "size_type cond_index)'\n") +
471  " File not found: " + dir.final_state_json(cond_index).string());
472  }
473 
474  // write file
475  fs::ofstream sout(dir.POSCAR_final(cond_index));
476  _log << "write: " << dir.POSCAR_final(cond_index) << "\n";
478  p.sort();
479  p.print(sout);
480  return;
481 }
482 
487 void write_POSCAR_trajectory(const MonteCarlo &mc, size_type cond_index,
488  Log &_log) {
490  fs::create_directories(dir.trajectory_dir(cond_index));
491 
492  std::vector<size_type> pass;
493  std::vector<size_type> step;
494  std::vector<ConfigDoF> trajectory;
495 
496  if (mc.settings().write_json()) {
497  std::string filename = dir.trajectory_json(cond_index).string() + ".gz";
498 
499  if (!fs::exists(filename)) {
500  throw std::runtime_error(
501  std::string("ERROR in 'write_POSCAR_trajectory(const MonteCarlo &mc, "
502  "size_type cond_index)'\n") +
503  " File not found: " + filename);
504  }
505 
506  gz::igzstream sin(filename.c_str());
507  jsonParser json(sin);
508  for (auto it = json["Pass"].cbegin(); it != json["Pass"].cend(); ++it) {
509  pass.push_back(it->get<size_type>());
510  }
511  for (auto it = json["Step"].cbegin(); it != json["Step"].cend(); ++it) {
512  step.push_back(it->get<size_type>());
513  }
514  for (auto it = json["DoF"].cbegin(); it != json["DoF"].cend(); ++it) {
515  trajectory.push_back(
516  it->get<ConfigDoF>(mc.supercell().prim(), mc.supercell().volume()));
517  }
518 
519  } else if (mc.settings().write_csv()) {
520  std::string filename = dir.trajectory_csv(cond_index).string() + ".gz";
521 
522  if (!fs::exists(filename)) {
523  throw std::runtime_error(
524  std::string("ERROR in 'write_POSCAR_trajectory(const MonteCarlo &mc, "
525  "size_type cond_index)'\n") +
526  " File not found: " + filename);
527  }
528 
529  gz::igzstream sin(filename.c_str());
530 
531  // skip the header line
532  sin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
533 
534  size_type _pass, _step;
535  ConfigDoF config_dof(Configuration(mc.supercell()).configdof());
536 
537  while (sin) {
538  sin >> _pass >> _step;
539  pass.push_back(_pass);
540  step.push_back(_step);
541  for (size_type i = 0; i < config_dof.size(); i++) {
542  sin >> config_dof.occ(i);
543  }
544  trajectory.push_back(config_dof);
545  }
546  }
547 
548  for (size_type i = 0; i < trajectory.size(); i++) {
549  // POSCAR title comment is printed with "Sample: # Pass: # Step: #"
550  std::stringstream ss;
551  ss << "Sample: " << i << " Pass: " << pass[i] << " Step: " << step[i];
552 
553  // write file
554  fs::ofstream sout(dir.POSCAR_snapshot(cond_index, i));
555  _log << "write: " << dir.POSCAR_snapshot(cond_index, i) << "\n";
556  VaspIO::PrintPOSCAR p(make_simple_structure(mc.supercell(), trajectory[i]));
557  p.set_title(ss.str());
558  p.sort();
559  p.print(sout);
560  sout.close();
561  }
562 
563  return;
564 }
565 
566 } // namespace Monte
567 } // namespace CASM
Index size() const
Number of sites in the ConfigDoF.
Definition: ConfigDoF.cc:11
int & occ(Index i)
Reference occupation value on site i.
Definition: ConfigDoF.cc:34
const ConfigDoF & configdof() const
const Access the DoF
Extract data from objects of 'DataObject' class.
void push_back(const BaseDatumFormatter< DataObject > &new_formatter, const std::string &args)
A DatumFormatter that returns a value of specified type, via functions that may be specified at runti...
Definition: Log.hh:48
Eigen::VectorBlock< const Eigen::VectorXd > observations() const
Return all observations.
Definition: MCData.hh:40
MonteCarloDirectoryStructure(fs::path output_dir)
Definition: MonteIO.cc:27
Interface base class for all types of Monte Carlo simulations (not meant to be used polymorphically)
Definition: MonteCarlo.hh:44
std::pair< bool, size_type > is_equilibrated() const
Returns pair(true, equil_samples) if required equilibration has occured for all samplers that must co...
Definition: MonteCarlo.cc:69
const Supercell & supercell() const
const Access the Supercell that *this is based on
Definition: MonteCarlo.hh:80
const MonteSettings & settings() const
const Access settings used for construction
Definition: MonteCarlo.hh:74
const PrimClex & primclex() const
const Access the PrimClex that *this is based on
Definition: MonteCarlo.hh:77
const std::vector< ConfigDoF > & trajectory() const
const Access snapshots of the Monte Carlo calculation
Definition: MonteCarlo.hh:159
const ConfigDoF & configdof() const
const Access current microstate
Definition: MonteCarlo.hh:93
const SamplerMap & samplers() const
const Access sampler map
Definition: MonteCarlo.hh:149
const SampleTimes & sample_times() const
const Access a vector of std::pair<pass, step> indicating when samples were taken
Definition: MonteCarlo.hh:153
An abstract base class for sampling and storing data observations.
Definition: MonteSampler.hh:26
const MCData & data() const
const Access the raw data observation container
Settings for Monte Carlo calculations.
const fs::path output_directory() const
Directory where output should go.
bool write_trajectory() const
Returns true if snapshots are requested.
bool write_observations() const
Writes all observations.
bool write_csv() const
Write csv versions of files? (csv is the default format if no 'output_format' given)
bool write_json() const
Write json versions of files?
Structure specifies the lattice and atomic basis of a crystal.
Definition: Structure.hh:30
const std::vector< xtal::Site > & basis() const
Definition: Structure.hh:102
Index volume() const
Return number of primitive cells that fit inside of *this.
Definition: Supercell.cc:227
const Structure & prim() const
Definition: Supercell.cc:113
Print POSCAR with formating options.
Definition: VaspIO.hh:40
void set_title(std::string title)
Set title.
Definition: VaspIO.hh:61
void sort()
Default sort is by atom name.
Definition: VaspIO.cc:50
void print(std::ostream &sout) const
Print POSCAR to stream.
Definition: VaspIO.cc:56
static jsonParser object()
Returns an empty json object.
Definition: jsonParser.hh:395
static jsonParser array()
Returns an empty json array.
Definition: jsonParser.hh:409
const_iterator cend() const
Returns const_iterator to end of JSON object or JSON array.
Definition: jsonParser.cc:533
void write(const std::string &file_name, unsigned int indent=2, unsigned int prec=12) const
Write json to file.
Definition: jsonParser.cc:196
std::string to_string(ENUM val)
Return string representation of enum class.
Definition: io_traits.hh:172
const PrimType & prim() const
const Access to primitive Structure
Definition: PrimClex.cc:262
jsonParser & push_back(const T &value, Args &&... args)
Definition: jsonParser.hh:684
T get(Args &&... args) const
Get data from json, using one of several alternatives.
Definition: jsonParser.hh:716
DoF_impl::OccupationDoFTraits occupation()
GenericDatumFormatter< double, std::pair< ConstMonteCarloPtr, size_type > > MonteCarloObservationFormatter(std::string prop_name)
Print value of observation.
Definition: MonteIO.cc:184
GenericDatumFormatter< double, ConstMonteCarloPtr > MonteCarloPrecFormatter(std::string prop_name)
Print calculated precision of property values: prec(<prop_name>)
Definition: MonteIO.cc:49
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....
Definition: MonteIO.cc:260
void write_POSCAR_initial(const MonteCarlo &mc, size_type cond_index, Log &_log)
For the initial state, write a POSCAR file.
Definition: MonteIO.cc:429
GenericDatumFormatter< size_type, std::pair< ConstMonteCarloPtr, size_type > > MonteCarloStepFormatter()
Print Step number of observation.
Definition: MonteIO.cc:172
void write_POSCAR_final(const MonteCarlo &mc, size_type cond_index, Log &_log)
For the final state, write a POSCAR file.
Definition: MonteIO.cc:458
GenericDatumFormatter< double, ConstMonteCarloPtr > MonteCarloMeanFormatter(std::string prop_name)
Print mean property values: <prop_name>
Definition: MonteIO.cc:31
DataFormatter< std::pair< ConstMonteCarloPtr, size_type > > make_observation_formatter(const MonteCarlo &mc)
Make a observation formatter.
Definition: MonteIO.cc:223
GenericDatumFormatter< size_type, ConstMonteCarloPtr > MonteCarloNAvgSamplesFormatter()
Print number of samples used in calculating means.
Definition: MonteIO.cc:148
GenericDatumFormatter< bool, ConstMonteCarloPtr > MonteCarloIsConvergedFormatter()
Print if converged.
Definition: MonteIO.cc:125
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....
Definition: MonteIO.cc:325
GenericDatumFormatter< int, std::pair< ConstMonteCarloPtr, size_type > > MonteCarloOccFormatter(size_type occ_index)
Print value of a particular occupation variable.
Definition: MonteIO.cc:198
GenericDatumFormatter< double, ConstMonteCarloPtr > MonteCarloCovFormatter(std::string prop_name1, std::string prop_name2)
Print covariance: cov(prop_name1, prop_name2)
Definition: MonteIO.cc:96
GenericDatumFormatter< bool, ConstMonteCarloPtr > MonteCarloIsEquilibratedFormatter()
Print if equilibrated (not counting explicitly requested equilibration)
Definition: MonteIO.cc:114
GenericDatumFormatter< size_type, ConstMonteCarloPtr > MonteCarloNEquilSamplesFormatter()
Print number of samples used for equilibration (not counting explicitly requested equilibration)
Definition: MonteIO.cc:137
void write_POSCAR_trajectory(const MonteCarlo &mc, size_type cond_index, Log &_log)
For every snapshot taken, write a POSCAR file.
Definition: MonteIO.cc:487
GenericDatumFormatter< size_type, std::pair< ConstMonteCarloPtr, size_type > > MonteCarloPassFormatter()
Print Pass number of observation.
Definition: MonteIO.cc:160
DataFormatter< std::pair< ConstMonteCarloPtr, size_type > > make_trajectory_formatter(const MonteCarlo &mc)
Make a trajectory formatter.
Definition: MonteIO.cc:246
Main CASM namespace.
Definition: APICommand.hh:8
xtal::SimpleStructure make_simple_structure(Supercell const &_scel, ConfigDoF const &_dof, std::vector< DoFKey > const &_which_dofs={})
Construct from ConfigDoF _dof belonging to provided Supercell _scel.
Eigen::VectorXd VectorXd
T max(const T &A, const T &B)
Definition: CASM_math.hh:95
DirectoryStructure const & dir
Definition: settings.cc:136
Functor to help evaluate covariance.
Definition: MonteIO.hh:144
double operator()(const ConstMonteCarloPtr &mc)
Definition: MonteIO.cc:66
std::string prop_name2
Definition: MonteIO.hh:151
std::string prop_name1
Definition: MonteIO.hh:150