CASM  1.1.0
A Clusters Approach to Statistical Mechanics
SuperConfigEnumInterface.cc
Go to the documentation of this file.
2 
3 #include "casm/app/APICommand.hh"
13 #include "casm/clex/PrimClex.hh"
14 #include "casm/clex/ScelEnum.hh"
19 
20 namespace CASM {
21 
22 std::string SuperConfigEnumInterface::desc() const {
23  std::string description =
24  "The SuperConfigEnum method generates tilings of sub-configurations in "
25  "selected \n"
26  "supercells. The method works as follows: \n"
27  "- Select a unit cell which all configurations tile into \n"
28  "- Generate all unit-cell-filling equivalents of the input "
29  "configurations. \n"
30  "- Generate supercells of the unit cell and tile the supercells with all "
31  "\n"
32  " combinations of the unit-cell-filling sub-configurations. Any global "
33  "DoF are \n"
34  " set to zero value. \n\n";
35 
36  std::string custom_options =
37  " supercells: object, ScelEnum JSON settings (required)\n"
38  " Supercells to be tiled with selected configuration, specified in "
39  "terms of\n"
40  " size and unit cell via a JSON object conforming to the format of "
41  "'ScelEnum'\n"
42  " JSON settings \"min\", \"max\", \"dirs\", and \"unit_cell\". See "
43  "'ScelEnum'\n"
44  " description for more details. The \"unit_cell\" must be a supercell "
45  "of all \n"
46  " all sub-configurations. \n\n"
47 
48  " confignames: Array of strings (required) \n"
49  " Names of the sub-configurations that can be tiled into the "
50  "\"unit_cell\".\n"
51  " Ex: \"confignames\" : "
52  "[\"SCEL1_1_1_1_0_0_0/1\",\"SCEL2_2_1_1_0_0_0/3\"]\n\n"
53 
54  " config_selection: string (optional) \n"
55  " Name of a selection of configurations to be tiled into selected "
56  "supercells.\n\n";
57 
58  std::string examples =
59 
60  " Examples:\n"
61  " To enumerate super-configurations of listed sub-configurations:\n"
62  " casm enum --method SuperConfigEnum -i \n"
63  " '{ \n"
64  " \"supercells\": { \n"
65  " \"max\": 4, \n"
66  " \"unit_cell\": \"SCEL2_1_2_1_0_0_0\" \n"
67  " },\n"
68  " \"confignames\": [\n"
69  " \"SCEL1_1_1_1_0_0_0/0\",\n"
70  " \"SCEL2_1_2_1_0_0_0/0\",\n"
71  " \"SCEL2_1_2_1_0_0_0/1\"\n"
72  " ]\n"
73  " }' \n"
74  "\n"
75  " To enumerate super-configurations of listed sub-configurations from "
76  "a \n"
77  " selection file:\n"
78  " casm enum --method SuperConfigEnum -i \n"
79  " '{ \n"
80  " \"supercells\": { \n"
81  " \"max\": 4, \n"
82  " \"unit_cell\": \"SCEL2_1_2_1_0_0_0\" \n"
83  " }, \n"
84  " \"config_selection\": \"selection_filename\"\n"
85  " }' \n"
86  "\n";
87 
88  return name() + ": \n\n" + description + custom_options + examples;
89 }
90 
91 std::string SuperConfigEnumInterface::name() const {
93 }
94 
95 // check that the input configurations fit in "shared_unit_supercell"
97  ParentInputParser &parser,
98  DB::Selection<Configuration> const &config_selection,
99  Supercell const &supercell) {
100  auto it = config_selection.selected().begin();
101  auto end = config_selection.selected().end();
102  for (; it != end; ++it) {
103  if (!is_valid_sub_configuration(it->ideal_lattice(), supercell)) {
104  std::stringstream msg;
105  msg << it.name() << " is not a valid sub configuration.";
106  parser.error.insert(msg.str());
107  }
108  }
109 }
110 
112  PrimClex &primclex, jsonParser const &json_options,
113  jsonParser const &cli_options_as_json) const {
114  Log &log = CASM::log();
115 
116  log.subsection().begin("SuperConfigEnum");
117  ParentInputParser parser =
118  make_enum_parent_parser(log, json_options, cli_options_as_json);
119  std::runtime_error error_if_invalid{
120  "Error reading SuperConfigEnum JSON input"};
121 
122  log.custom("Checking input");
123 
124  // 1) Parse ConfigEnumOptions ------------------
125  auto options_parser_ptr = parser.parse_as<ConfigEnumOptions>(
127  primclex.settings().query_handler<Configuration>().dict());
128  report_and_throw_if_invalid(parser, log, error_if_invalid);
129  ConfigEnumOptions const &options = *options_parser_ptr->value;
130  print_options(log, options);
131  log.set_verbosity(options.verbosity);
132 
133  // 2) Parse supercells ------------------
134 
135  auto shared_prim = primclex.shared_prim();
136  auto scel_enum_props_subparser =
137  parser.subparse_if<xtal::ScelEnumProps>("supercells");
138  report_and_throw_if_invalid(parser, log, error_if_invalid);
139 
140  // these parameters define which "target supercells" will be filled by
141  // sub-configurations
142  xtal::ScelEnumProps const &scel_enum_props =
143  *scel_enum_props_subparser->value;
144 
145  // this is the smallest of the target supercells, the rest are supercells of
146  // this
147  auto shared_unit_supercell = std::make_shared<Supercell>(
148  shared_prim, scel_enum_props.generating_matrix().cast<long>());
149 
150  // make target supercells (to be filled by sub-configurations to create
151  // super-configurations)
152  typedef std::string SupercellName;
153  std::map<SupercellName, std::shared_ptr<Supercell const>> target_supercells;
154  {
155  ScelEnumByProps enumerator{shared_prim, scel_enum_props};
156  for (auto const &supercell : enumerator) {
157  target_supercells.emplace(supercell.name(),
158  std::make_shared<Supercell const>(supercell));
159  }
160  }
161  print_initial_states(log, target_supercells);
162 
163  // 3) Parse sub-configurations --------------
164 
165  DB::Selection<Configuration> config_selection;
166  try {
167  config_selection = DB::make_selection<Configuration>(
168  primclex.db<Configuration>(), parser.self, "confignames",
169  "config_selection");
170  } catch (std::exception &e) {
171  std::stringstream msg;
172  msg << "Error reading configurations: " << e.what();
173  parser.error.insert(msg.str());
174  }
175 
176  // logic check: require input configurations can fill the unit supercell
177  require_valid_sub_configurations(parser, config_selection,
178  *shared_unit_supercell);
179 
180  // if valid at this point, everything should be valid to make sub_configs and
181  // target_supercells
182  report_and_throw_if_invalid(parser, log, error_if_invalid);
183 
184  // create the sub-configurations that will be building blocks of the
185  // super-configurations note: the sub-configurations are themselves
186  // super-configurations (of the input
187  // configurations) that fill the shared_unit_supercell
188  std::vector<Configuration> sub_configs;
189  {
190  auto it = config_selection.selected().begin();
191  auto end = config_selection.selected().end();
192  Index n_before = 0;
193  for (; it != end; ++it) {
194  log << "Making equivalents of " << it.name() << ": " << std::flush;
195  make_all_super_configurations(*it, shared_unit_supercell,
196  std::back_inserter(sub_configs));
197  log << sub_configs.size() - n_before << std::endl;
198  n_before = sub_configs.size();
199  }
200  // TODO: check for and remove duplicates caused by non-primitive input
201  // configurations?
202  log << "Total sub-configurations, including all equivalents: "
203  << sub_configs.size() << std::flush;
204  }
205 
206  // 4) Enumerate configurations ------------------
207 
208  // Functor to construct SuperConfigEnum for each target supercell
209  auto make_enumerator_f =
210  [&](Index index, std::string name,
211  std::shared_ptr<Supercell const> const &target_supercell) {
212  return SuperConfigEnum{*target_supercell, sub_configs.begin(),
213  sub_configs.end()};
214  };
215 
219  formatter.push_back(ConfigEnumIO::name<ConfigEnumDataType>(),
220  ConfigEnumIO::selected<ConfigEnumDataType>(),
221  ConfigEnumIO::is_new<ConfigEnumDataType>(),
222  ConfigEnumIO::is_existing<ConfigEnumDataType>());
223  if (options.filter) {
224  formatter.push_back(
225  ConfigEnumIO::is_excluded_by_filter<ConfigEnumDataType>());
226  }
227  formatter.push_back(ConfigEnumIO::initial_state_index<ConfigEnumDataType>(),
228  ConfigEnumIO::initial_state_name<ConfigEnumDataType>());
229 
230  log << std::endl;
231  log.begin("SuperConfigEnum enumeration");
232 
233  enumerate_configurations(primclex, options, make_enumerator_f,
234  target_supercells.begin(), target_supercells.end(),
235  formatter);
236 
237  log.end_section();
238 }
239 
240 } // namespace CASM
std::shared_ptr< Structure const > shared_prim
boost::iterator_range< iterator > selected()
Definition: Selection.cc:237
Extract data from objects of 'DataObject' class.
void push_back(const BaseDatumFormatter< DataObject > &new_formatter, const std::string &args)
std::shared_ptr< InputParser< RequiredType > > parse_as(Args &&... args)
std::shared_ptr< InputParser< RequiredType > > subparse_if(fs::path option, Args &&... args)
Definition: Log.hh:48
void end_section()
End a section.
Definition: Log.hh:192
void set_verbosity(int _verbosity)
Definition: Log.cc:57
void custom(const std::string &what)
Definition: Log.hh:139
Log & subsection()
Create a subsection.
Definition: Log.hh:186
void begin(const std::string &what)
Definition: Log.hh:114
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:55
Given a selection of Configurations, enumerate all tilings into some supercell.
static const std::string enumerator_name
void run(PrimClex &primclex, jsonParser const &json_options, jsonParser const &cli_options_as_json) const override
std::string desc() const override
std::string name() const override
Enumeration method name (i.e. "ConfigEnumAllOccupations")
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:51
Data structure for holding supercell enumeration properties.
Eigen::Matrix3i generating_matrix() const
ConfigEnumData< ConfigEnumSiteDoFs, ConfigEnumInput > ConfigEnumDataType
Main CASM namespace.
Definition: APICommand.hh:8
std::string description(const SymOp &op, const xtal::Lattice &lat, SymInfoOptions opt=SymInfoOptions())
Print SymInfo to string.
void print_initial_states(Log &log, NamedInitialStatesType const &named_initial_states)
Log & log()
Definition: Log.hh:424
ParentInputParser make_enum_parent_parser(Log &log, jsonParser const &json_options, jsonParser const &cli_options_as_json)
Combine –input / –settings JSON with CLI options.
bool is_valid_sub_configuration(xtal::Lattice const &sub_configuration_lattice, Supercell const &supercell)
void enumerate_configurations(PrimClex const &primclex, ConfigEnumOptions const &options, MakeEnumeratorFunction make_enumerator_f, InputNameValuePairIterator name_value_pairs_begin, InputNameValuePairIterator name_value_pairs_end, DataFormatter< ConfigEnumDataType > const &formatter)
Enumerate configurations.
void report_and_throw_if_invalid(KwargsParser const &parser, Log &log, ErrorType error)
void print_options(Log &log, ConfigEnumOptions const &options)
Definition: stream_io.cc:6
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
void require_valid_sub_configurations(ParentInputParser &parser, DB::Selection< Configuration > const &config_selection, Supercell const &supercell)
ConfigOutputIterator make_all_super_configurations(Configuration const &configuration, std::shared_ptr< Supercell const > shared_supercell, ConfigOutputIterator result)
Make all super configurations that fill a particular supercell.
PrimClex * primclex
Definition: settings.cc:135
Options for the enumerate_configurations function.
int verbosity
Printing verbosity level.
std::function< bool(Configuration const &)> filter
If filter(configuration)==true, keep configuration, else skip.
jsonParser const & self
Definition: InputParser.hh:81
std::set< std::string > error
Definition: Validator.hh:11