CASM  1.1.0
A Clusters Approach to Statistical Mechanics
dof_space_analysis.cc
Go to the documentation of this file.
2 
3 #include <boost/filesystem.hpp>
4 
6 #include "casm/casm_io/Log.hh"
8 #include "casm/clex/Supercell.hh"
15 #include "casm/symmetry/json_io.hh"
16 
17 namespace CASM {
18 
19 namespace DoFSpaceIO {
20 
21 OutputImpl::Error::Error(Index _state_index, std::string _identifier,
22  DoFKey _dof_key, std::string _what, jsonParser _data)
23  : state_index(_state_index),
24  identifier(_identifier),
25  dof_key(_dof_key),
26  what(_what),
27  data(_data) {}
28 
32  std::string const &identifier,
33  ConfigEnumInput const &config_enum_input,
34  std::vector<PermuteIterator> const &group) {
35  Lattice config_lattice = config_enum_input.configuration().ideal_lattice();
38  make_sym_group(group.begin(), group.end(), config_lattice);
40  make_point_group(group.begin(), group.end(), config_lattice);
41  this->write_symmetry(state_index, identifier, config_enum_input,
43 }
44 
46  make_symmetry_adapted_dof_space_error const &e, Index state_index,
47  DoFSpace const &dof_space, std::string const &identifier,
48  ConfigEnumInput const &config_enum_input,
49  std::optional<SymRepTools_v2::VectorSpaceSymReport> const &sym_report) {
50  jsonParser json;
51  to_json(dof_space, json, identifier, config_enum_input, sym_report);
52  errors().emplace_back(state_index, identifier, dof_space.dof_key(), e.what(),
53  json);
54 }
55 
59  if (!errors().size()) {
60  return;
61  }
62 
63  fs::path output_path = fs::current_path() / "dof_space_errors.json";
64  Index i = 1;
65  while (fs::exists(output_path)) {
66  output_path = fs::current_path() / (std::string("dof_space_errors.") +
67  std::to_string(i) + ".json");
68  ++i;
69  }
70 
72  for (auto const e : errors()) {
73  jsonParser tjson;
74  tjson["state_index"] = e.state_index;
75  tjson["identifier"] = e.identifier;
76  tjson["dof"] = e.dof_key;
77  tjson["what"] = e.what;
78  tjson["data"] = e.data;
79  json.push_back(tjson);
80  }
81  CASM::log() << "Encountered " << errors().size() << " errors" << std::endl;
82 
83  fs::ofstream outfile{output_path};
84  json.print(outfile);
85  CASM::log() << "Writing: " << output_path << std::endl;
86 }
87 
89  std::string const &identifier,
90  ConfigEnumInput const &config_enum_input,
92  SymGroup const &factor_group,
94  _check_config(state_index, identifier, config_enum_input);
95  fs::path output_dir = _output_dir(state_index, identifier, config_enum_input);
96 
97  // Write lattice point group
98  {
99  jsonParser json;
101  fs::path output_path = output_dir / "lattice_point_group.json";
102  fs::ofstream outfile{output_path};
103  json.print(outfile);
104  CASM::log() << "Writing: " << output_path << std::endl;
105  }
106 
107  // Write factor group
108  {
109  jsonParser json;
111  fs::path output_path = output_dir / "factor_group.json";
112  fs::ofstream outfile{output_path};
113  json.print(outfile);
114  CASM::log() << "Writing: " << output_path << std::endl;
115  }
116 
117  // Write crystal point group
118  {
119  jsonParser json;
121  fs::path output_path = output_dir / "crystal_point_group.json";
122  fs::ofstream outfile{output_path};
123  json.print(outfile);
124  CASM::log() << "Writing: " << output_path << std::endl;
125  }
126 }
127 
128 // void DirectoryOutput::write_config(
129 // Index state_index,
130 // std::string const &identifier,
131 // ConfigEnumInput const &config_enum_input) {
132 //
133 // _check_config(state_index, identifier, config_enum_input);
134 // fs::path output_dir = _output_dir(state_index, identifier,
135 // config_enum_input);
136 //
137 // fs::path output_path = output_dir / "config.json";
138 // fs::ofstream outfile {output_path};
139 // jsonParser json;
140 // to_json(config_enum_input.configuration(), json);
141 // json.print(outfile);
142 // CASM::log() << "Writing: " << output_path << std::endl << std::endl;
143 // }
144 
146  Index state_index, std::string const &identifier,
147  ConfigEnumInput const &config_enum_input) {
148  _check_config(state_index, identifier, config_enum_input);
149  fs::path output_dir = _output_dir(state_index, identifier, config_enum_input);
150 
151  fs::path output_path = output_dir / "structure.json";
152  fs::ofstream outfile{output_path};
153  jsonParser json;
154  to_json(make_simple_structure(config_enum_input.configuration()), json);
155  json.print(outfile);
156  CASM::log() << "Writing: " << output_path << std::endl << std::endl;
157 }
158 
160  Index state_index, DoFSpace const &dof_space, std::string const &identifier,
161  ConfigEnumInput const &config_enum_input,
162  std::optional<SymRepTools_v2::VectorSpaceSymReport> const &sym_report) {
163  _check_config(state_index, identifier, config_enum_input);
164  fs::path output_dir = _output_dir(state_index, identifier, config_enum_input);
165 
166  jsonParser json;
167  to_json(dof_space, json, identifier, config_enum_input, sym_report);
168 
169  std::string filename = "dof_space_" + dof_space.dof_key() + ".json";
170  fs::path output_path = output_dir / filename;
171  json.write(output_path);
172  CASM::log() << "Writing: " << output_path << std::endl << std::endl;
173 }
174 
176  : m_dir(dir) {}
177 
181  Index state_index, std::string const &identifier,
182  ConfigEnumInput const &config_enum_input) {
183  Configuration const &configuration = config_enum_input.configuration();
184  // These should not occur for now. They should be prevented by
185  // require_database_configurations.
186  // TODO: add support for other dof space analyses
187  if (configuration.id() == "none") {
188  throw std::runtime_error(
189  "Error in output_dof_space: Cannot output to symmetry directory, "
190  "configuration does not exist in database. Choose a different output "
191  "method.");
192  }
193  if (identifier != configuration.name()) {
194  throw std::runtime_error(
195  "Error in output_dof_space: Cannot output to symmetry directory, "
196  "unknown name error. Choose a different output method.");
197  }
198  if (config_enum_input.sites().size() != configuration.size()) {
199  throw std::runtime_error(
200  "Error in output_dof_space: Cannot output to symmetry directory, "
201  "incomplete site selection. Choose a different output method.");
202  }
203 }
204 
207  Index state_index, std::string const &identifier,
208  ConfigEnumInput const &config_enum_input) {
209  fs::path output_dir =
210  m_dir.symmetry_dir(config_enum_input.configuration().name());
211  fs::create_directories(output_dir);
212  return output_dir;
213 }
214 
216  : m_output_dir(output_dir) {
217  if (fs::exists(m_output_dir / "dof_space")) {
218  throw std::runtime_error(
219  "Error in output_dof_space: \"dof_space\" directory "
220  "already exists. Will not overwrite.");
221  }
222 }
223 
226  Index state_index, std::string const &identifier,
227  ConfigEnumInput const &config_enum_input) {
228  return;
229 }
230 
233  Index state_index, std::string const &identifier,
234  ConfigEnumInput const &config_enum_input) {
235  std::string dirname = std::string("state.") + std::to_string(state_index);
236  fs::path output_dir = m_output_dir / "dof_space" / dirname;
237  fs::create_directories(output_dir);
238  return output_dir;
239 }
240 
242  : m_combined_json(jsonParser::array()), m_output_dir(output_dir) {
243  fs::path output_path = m_output_dir / "dof_space.json";
244  if (fs::exists(output_path)) {
245  throw std::runtime_error(
246  "Error in output_dof_space: \"dof_space.json\" file "
247  "already exists. Will not overwrite.");
248  }
249 }
250 
252  fs::path output_path = m_output_dir / "dof_space.json";
253  fs::ofstream outfile{output_path};
254  m_combined_json.print(outfile);
255  CASM::log() << "Writing: " << output_path << std::endl;
256 }
257 
259  Index state_index, std::string const &identifier,
260  ConfigEnumInput const &config_enum_input,
262  SymGroup const &crystal_point_group) {
263  jsonParser &output_json = _output_json(state_index);
264  write_symgroup(lattice_point_group, output_json["lattice_point_group"]);
265  write_symgroup(factor_group, output_json["factor_group"]);
266  write_symgroup(crystal_point_group, output_json["crystal_point_group"]);
267 }
268 
269 // void CombinedJsonOutput::write_config(
270 // Index state_index,
271 // std::string const &identifier,
272 // ConfigEnumInput const &config_enum_input) {
273 //
274 // jsonParser &output_json = _output_json(state_index);
275 // to_json(config_enum_input.configuration(), output_json["config"]);
276 // }
277 
279  Index state_index, std::string const &identifier,
280  ConfigEnumInput const &config_enum_input) {
281  jsonParser &output_json = _output_json(state_index);
282  to_json(make_simple_structure(config_enum_input.configuration()),
283  output_json["structure"]);
284 }
285 
287  Index state_index, DoFSpace const &dof_space, std::string const &identifier,
288  ConfigEnumInput const &config_enum_input,
289  std::optional<SymRepTools_v2::VectorSpaceSymReport> const &sym_report) {
290  jsonParser &output_json =
291  _output_json(state_index)["dof_space"][dof_space.dof_key()];
292  to_json(dof_space, output_json, identifier, config_enum_input, sym_report);
293 }
294 
296  while (m_combined_json.size() < state_index) {
298  }
299  return m_combined_json[state_index - 1];
300 }
301 
302 void output_dof_space(Index state_index, std::string const &identifier,
303  ConfigEnumInput const &input_state,
304  DoFSpaceAnalysisOptions const &options,
305  OutputImpl &output) {
306  Log &log = CASM::log();
307  log.begin(identifier);
309 
310  auto const &sym_info = input_state.configuration().supercell().sym_info();
311  std::vector<PermuteIterator> group = make_invariant_subgroup(input_state);
312 
313  if (options.write_symmetry) {
314  Lattice config_lattice = input_state.configuration().ideal_lattice();
317  make_sym_group(group.begin(), group.end(), config_lattice);
319  make_point_group(group.begin(), group.end(), config_lattice);
320  output.write_symmetry(state_index, identifier, input_state,
323  }
324 
325  // if(options.write_config) {
326  // output.write_config(state_index, identifier, config_enum_input);
327  // }
328 
329  if (options.write_structure) {
330  output.write_structure(state_index, identifier, input_state);
331  }
332 
333  for (DoFKey const &dof : options.dofs) {
334  log << "Working on: " << identifier << " " << dof << std::endl;
335  DoFSpace dof_space = make_dof_space(dof, input_state);
336  std::optional<SymRepTools_v2::VectorSpaceSymReport> report;
337  try {
338  if (options.sym_axes) {
340  dof_space, sym_info, group, options.calc_wedge, report);
341  }
343  log << "Error: " << e.what() << std::endl;
344  log << "skipping: " << identifier << " " << dof << std::endl << std::endl;
345  output.write_dof_space_error(e, state_index, dof_space, identifier,
346  input_state, report);
347  continue;
348  }
349  output.write_dof_space(state_index, dof_space, identifier, input_state,
350  report);
351  }
352 
354  log << std::endl;
355 }
356 
358  std::vector<std::pair<std::string, ConfigEnumInput>> const &named_inputs,
359  DoFSpaceAnalysisOptions const &options, OutputImpl &output) {
360  // For each state, for each DoF type specified, perform analysis and write
361  // files.
362  Index state_index{0};
363  for (auto const &named_input : named_inputs) {
364  std::string identifier = named_input.first;
365  ConfigEnumInput const &input_state = named_input.second;
366  output_dof_space(state_index, identifier, input_state, options, output);
367 
368  ++state_index;
369  }
370  output.write_errors();
371 }
372 
373 } // namespace DoFSpaceIO
374 
375 } // namespace CASM
const Lattice & ideal_lattice() const
const Supercell & supercell() const
Get the Supercell for this Configuration.
Index size() const
Returns number of sites, NOT the number of primitives that fit in here.
Specification of CASM project directory structure.
fs::path symmetry_dir() const
Return symmetry directory path.
DoFKey const & dof_key() const
Definition: DoFSpace.cc:205
jsonParser & _output_json(Index state_index)
void write_symmetry(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input, std::vector< PermuteIterator > const &group)
void write_structure(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input) override
Write input state structure.
void write_dof_space(Index state_index, DoFSpace const &dof_space, std::string const &identifier, ConfigEnumInput const &config_enum_input, std::optional< SymRepTools_v2::VectorSpaceSymReport > const &sym_report) override
Write dof space analysis.
void write_symmetry(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input, std::vector< PermuteIterator > const &group)
void write_dof_space(Index state_index, DoFSpace const &dof_space, std::string const &identifier, ConfigEnumInput const &config_enum_input, std::optional< SymRepTools_v2::VectorSpaceSymReport > const &sym_report) override
Write dof space analysis.
void write_structure(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input) override
Write input state structure.
std::vector< Error > const & errors() const
void write_dof_space_error(make_symmetry_adapted_dof_space_error const &e, Index state_index, DoFSpace const &dof_space, std::string const &identifier, ConfigEnumInput const &config_enum_input, std::optional< SymRepTools_v2::VectorSpaceSymReport > const &sym_report)
Write dof space analysis error information.
void write_symmetry(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input, std::vector< PermuteIterator > const &group)
virtual void write_dof_space(Index state_index, DoFSpace const &dof_space, std::string const &identifier, ConfigEnumInput const &config_enum_input, std::optional< SymRepTools_v2::VectorSpaceSymReport > const &sym_report)=0
Write dof space analysis.
virtual void write_structure(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input)=0
Write input state structure.
fs::path _output_dir(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input) override
For SequentialDirectoryOutput return output directory path.
void _check_config(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input) override
For SequentialDirectoryOutput, any input state is allowed.
fs::path _output_dir(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input) override
For SymmetryDirectoryOutput return output directory path in symmetry dir.
void _check_config(Index state_index, std::string const &identifier, ConfigEnumInput const &config_enum_input) override
SymmetryDirectoryOutput(DirectoryStructure const &dir)
Definition: Log.hh:48
void begin(const std::string &what)
Definition: Log.hh:114
void increase_indent()
Definition: Log.hh:277
void decrease_indent()
Definition: Log.hh:279
const SupercellSymInfo & sym_info() const
Definition: Supercell.cc:265
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:42
static SymGroup lattice_point_group(Lattice const &_lat)
Definition: SymGroup.cc:779
static jsonParser object()
Returns an empty json object.
Definition: jsonParser.hh:395
size_type size() const
Definition: jsonParser.cc:487
static jsonParser array()
Returns an empty json array.
Definition: jsonParser.hh:409
void write(const std::string &file_name, unsigned int indent=2, unsigned int prec=12) const
Write json to file.
Definition: jsonParser.cc:196
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
Definition: jsonParser.cc:188
std::string to_string(ENUM val)
Return string representation of enum class.
Definition: io_traits.hh:172
std::set< Index > const & sites() const
Configuration const & configuration() const
std::vector< PermuteIterator > make_invariant_subgroup(ConfigEnumInput const &config_enum_input)
jsonParser & push_back(const T &value, Args &&... args)
Definition: jsonParser.hh:684
void output_dof_space(Index state_index, std::string const &identifier, ConfigEnumInput const &input_state, DoFSpaceAnalysisOptions const &options, OutputImpl &output)
void dof_space_analysis(std::vector< std::pair< std::string, ConfigEnumInput >> const &named_inputs, DoFSpaceAnalysisOptions const &options, OutputImpl &output)
SharedPrimFormatter< jsonParser > factor_group()
SharedPrimFormatter< jsonParser > lattice_point_group()
SharedPrimFormatter< jsonParser > crystal_point_group()
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.
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
Log & log()
Definition: Log.hh:424
DoFSpace make_dof_space(DoFKey dof_key, ConfigEnumInput const &input_state, std::optional< Eigen::MatrixXd > const &basis=std::nullopt)
Definition: DoFSpace.cc:487
SymGroup make_sym_group(const PermuteIteratorContainer &container, const Lattice &supercell_lattice)
Returns a SymGroup generated from a container of PermuteIterator.
std::string DoFKey
Definition: DoFDecl.hh:7
void write_symgroup(SymGroup const &grp, jsonParser &json)
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
DoFSpace make_symmetry_adapted_dof_space_v2(DoFSpace const &dof_space, SupercellSymInfo const &sym_info, std::vector< PermuteIterator > const &group, bool calc_wedges, std::optional< SymRepTools_v2::VectorSpaceSymReport > &symmetry_report)
Make DoFSpace with symmetry adapated basis.
Definition: DoFSpace.cc:635
SymGroup make_point_group(const PermuteIteratorContainer &container, const Lattice &supercell_lattice)
Returns a SymGroup generated from a container of PermuteIterator.
DirectoryStructure const & dir
Definition: settings.cc:136
Error(Index _state_index, std::string _identifier, DoFKey _dof_key, std::string _what, jsonParser _data)