23 json[
"sites"] = config_enum_input.
sites();
30 std::shared_ptr<Structure const>
const &
shared_prim) {
34 std::runtime_error error_if_invalid{
35 "Error reading ConfigEnumInput from JSON"};
43 std::shared_ptr<Structure const>
const &
shared_prim) {
44 auto configuration_ptr =
46 auto sites_ptr = parser.
require<std::set<Index>>(
"sites");
50 notstd::make_unique<ConfigEnumInput>(*configuration_ptr, *sites_ptr);
59 std::vector<std::pair<std::string, ConfigEnumInput>> &config_enum_input,
67 std::runtime_error error_if_invalid{
68 "Error reading std::vector<ConfigEnumInput> from JSON"};
83 std::string default_dirs{
"abc"};
84 Eigen::Matrix3i generating_matrix;
96 if (supercell_it == supercell_db.
end()) {
97 std::stringstream msg;
98 msg <<
"Error parsing \"unit_cell\": string value not equal to any "
99 "existing supercell name";
100 parser.
error.insert(msg.str());
103 supercell_it->sym_info().transformation_matrix_to_super().cast<
int>();
106 parser.
optional_else(generating_matrix,
"unit_cell", default_matrix);
110 std::stringstream msg;
111 msg <<
"The option \"existing_only\" is no longer supported. "
112 <<
"To select all existing supercells use \"supercell_selection\": "
114 parser.
error.insert(msg.str());
117 if (parser.
valid()) {
118 parser.
value = notstd::make_unique<xtal::ScelEnumProps>(
min,
max + 1, dirs,
125 return " scelnames: array of strings (optional, override with --scelnames) "
127 " Names of supercells used as input states. All sites will be set "
129 " listed occupant, and all other DoFs will be set to zero. Ex: "
132 " \"scelnames\": [\"SCEL1_1_1_1_0_0_0\", "
133 "\"SCEL2_2_1_1_0_0_0\"] \n\n"
135 " supercell_selection: string (optional) "
137 " Name of a selection of supercells to use as input states. "
140 " supercells: object, ScelEnum JSON settings (optional, override "
141 "with --min, --max) \n"
142 " Indicate supercells to use as input states in terms of size and "
144 " a JSON object conforming to the format of 'ScelEnum' JSON "
145 "settings \"min\", \n"
146 " \"max\", \"dirs\", and \"unit_cell\". See 'ScelEnum' description "
151 " confignames: array of strings (optional, override with "
153 " Names of configurations to be used as input states. All "
154 "specified sublattices or\n"
155 " sites will be enumerated on and all other DoFs will "
157 " maintain the values of the initial state. Ex: "
160 " \"confignames\": [\"SCEL1_1_1_1_0_0_0/1\", "
161 "\"SCEL2_2_1_1_0_0_0/3\"] \n\n"
163 " config_selection: string (optional) "
165 " Name of a selection of configurations to use as initial states. "
168 " config_list: array (optional) "
170 " Allows direct input of configurations that may not already exist "
172 " database via a JSON array of objects conforming to the "
173 "\"config.json\" format. \n"
174 " If the \"dof\" component is not included all sites will be set "
176 " listed occupant, and all other DoFs will be set to zero, as if "
185 " \"transformation_matrix_to_supercell\": [ "
195 " \"identifier\": \"custom_strain.1\", "
199 " \"global_dofs\" : { "
203 " \"values\" : [ 0.100000000000, 0.100000000000, "
204 "0.100000000000, 0.000000000000, 0.000000000000, 0.000000000000 ]\n"
209 " \"occ\" : [ 0, 0 ] "
218 " sublats: array of integers (optional, default none) "
220 " Selects sites by specifying sublattices. Each sublattice index "
221 "corresponds to a \n"
222 " basis site in prim.json, indexed from 0. Ex: "
225 " \"sublats\" : [0, 2] "
228 " sites: array of 4-entry integer arrays (optional, default none) \n"
229 " Selects sites by [b,i,j,k] convention, where 'b' is sublattice "
230 "index and [i,j,k]\n"
231 " specifies linear combinations of primitive-cell lattice vectors. "
234 " \"sites\" : [[0,0,0,0], "
239 " cluster_specs: object (optional) "
241 " JSON object specifying orbits of clusters to generate. Each "
242 "orbit prototype is \n"
243 " used to select sites on each input supercell or configuration. "
245 " supercells or configurations selected, and there are 10 orbits "
247 " there will be 4*10=40 initial states generated. The "
248 "\"cluster_specs\" option \n"
249 " cannot be used with the \"sublats\" or \"sites\" options. Expect "
252 " method: string (required) "
254 " Specify which cluster orbit generating method will be used. "
257 " - \"periodic_max_length\": Clusters differing by a lattice "
259 " considered equivalent. Cluster generation is truncated by "
261 " maximum distance between sites in a cluster for 2-point, "
263 " clusters. The point clusters comprising the asymmetric unit "
265 " structure are always included. After the cluster orbits are "
267 " the prim factor group symmetry, the orbits are broken into "
269 " reflecting the configuration factor group symmetry of the "
270 "input state. Any \n"
271 " orbits that are duplicated under periodic boundary "
272 "conditions are removed. \n\n"
274 " params: object (required) \n"
275 " Specifies parameters for the method selected by `method`. "
276 "Options depend on the \n"
277 " `method` chosen: \n\n"
279 " For method==\"periodic_max_length\": \n"
280 " orbit_branch_specs: object (optional)\n"
281 " Cluster generation is truncated by specifying the maximum "
283 " between sites in a cluster for each orbit branch (i.e. "
284 "2-point, 3-point, etc.\n"
285 " clusters). The 1-point clusters comprising the asymmetric "
287 " structure are always included. \n\n"
290 " \"orbit_branch_specs\": {\n"
291 " \"2\": { \"max_length\": 10.0 },\n"
292 " \"3\": { \"max_length\": 8.0 },\n"
296 " orbit_specs: array (optional) \n"
297 " An array of clusters which are used to generate and "
298 "include orbits of clusters \n"
299 " whether or not they meet the `max_length` truncation "
300 "criteria. See the \n"
301 " cluster input format below. Use the "
302 "\"include_subclusters\" option to force \n"
303 " generation of orbits for all subclusters of the specified "
306 " Example cluster, with \"Direct\" coordinates: \n"
308 " \"coordinate_mode\" : \"Direct\", \n"
310 " [ 0.000000000000, 0.000000000000, 0.000000000000 "
312 " [ 1.000000000000, 0.000000000000, 0.000000000000 "
314 " [ 2.000000000000, 0.000000000000, 0.000000000000 "
316 " [ 3.000000000000, 0.000000000000, 0.000000000000 "
318 " \"include_subclusters\" : true \n"
321 " Example cluster, with \"Integral\" coordinates: \n"
323 " \"coordinate_mode\" : \"Integral\", \n"
325 " [ 0, 0, 0, 0 ], \n"
326 " [ 0, 1, 0, 0 ], \n"
327 " [ 1, 0, 0, 0 ]], \n"
328 " \"include_subclusters\" : true \n"
410 InputParser<std::vector<std::pair<std::string, ConfigEnumInput>>> &parser,
412 DB::Database<Supercell> &supercell_db,
413 DB::Database<Configuration> &configuration_db) {
415 DB::Selection<Configuration> config_selection;
417 config_selection = DB::make_selection<Configuration>(
418 configuration_db, parser.self,
"confignames",
"config_selection");
419 }
catch (std::exception &e) {
420 std::stringstream msg;
421 msg <<
"Error creating input states from configurations: " << e.what();
422 parser.error.insert(msg.str());
436 typedef std::vector<std::pair<std::string, Configuration>> NamedConfiguration;
437 NamedConfiguration config_list;
439 if (parser.self.contains(
"config_list")) {
441 auto it = parser.self.find(
"config_list");
442 auto end = parser.self.end();
443 for (; it != end; ++it) {
444 auto config_ptr = it->make<Configuration>(
shared_prim);
445 std::string identifier =
446 it->get_if_else(
"identifier", config_ptr->name());
447 config_list.emplace_back(identifier, std::move(*config_ptr));
449 }
catch (std::exception &e) {
450 std::stringstream msg;
451 msg <<
"Error creating input states from config_list: " << e.what();
452 parser.error.insert(msg.str());
457 DB::Selection<Supercell> supercell_selection;
459 supercell_selection = DB::make_selection<Supercell>(
460 supercell_db, parser.self,
"scelnames",
"supercell_selection");
461 }
catch (std::exception &e) {
462 std::stringstream msg;
463 msg <<
"Error creating input states from supercells: " << e.what();
464 parser.error.insert(msg.str());
468 auto scel_enum_props_subparser =
469 parser.subparse_if<xtal::ScelEnumProps>(
"supercells", supercell_db);
472 std::vector<Index> sublats;
473 parser.optional(sublats,
"sublats");
474 for (
Index b : sublats) {
476 std::stringstream msg;
477 msg <<
"Error reading sublats: value out of range [0, "
479 parser.error.insert(msg.str());
484 std::vector<UnitCellCoord> sites;
485 parser.optional(sites,
"sites");
487 for (UnitCellCoord site_uccoord : sites) {
488 Index b = site_uccoord.sublattice();
490 std::stringstream msg;
491 msg <<
"Error reading sites[" << i
492 <<
"]: sublattice index out of range [0, "
494 parser.error.insert(msg.str());
501 if ((sublats.size() || sites.size()) &&
502 parser.self.contains(
"cluster_specs")) {
503 std::stringstream msg;
504 msg <<
"Error creating input states: "
505 <<
"cannot include \"cluster_specs\" with \"sublats\" or \"sites\"";
506 parser.error.insert(msg.str());
510 auto cluster_specs_subparser = parser.subparse_if<ClusterSpecs>(
512 if (cluster_specs_subparser->value) {
513 if (cluster_specs_subparser->value->periodicity_type() !=
515 std::stringstream msg;
516 msg <<
"Error creating input states: "
517 <<
"\"cluster_specs\" method must be \"periodic_max_length\"";
518 cluster_specs_subparser->error.insert(msg.str());
524 if (!parser.valid()) {
530 std::vector<std::pair<std::string, ConfigEnumInput>> config_enum_input;
531 for (
const auto &
config : config_selection.selected()) {
534 for (
const auto &named_config : config_list) {
535 config_enum_input.emplace_back(named_config.first, named_config.second);
537 for (
const auto &scel : supercell_selection.selected()) {
538 config_enum_input.emplace_back(scel.name(), scel);
540 if (scel_enum_props_subparser->value) {
541 ScelEnumByProps enumerator{
shared_prim, *scel_enum_props_subparser->value};
542 for (
auto const &supercell : enumerator) {
543 auto supercell_it = supercell_db.insert(supercell).first;
544 config_enum_input.emplace_back(supercell_it->name(), *supercell_it);
549 if (sublats.size() || sites.size()) {
550 for (
auto &input_name_value_pair : config_enum_input) {
552 input_name_value_pair.second.clear_sites();
554 std::stringstream ss;
555 if (sublats.size()) {
556 ss <<
", sublats=" << jsonParser{sublats};
557 input_name_value_pair.second.select_sublattices(sublats);
560 ss <<
", sites=" << jsonParser{sites};
561 input_name_value_pair.second.select_sites(sites);
563 input_name_value_pair.first += ss.str();
568 if (cluster_specs_subparser->value !=
nullptr) {
571 cluster_specs_subparser->value->make_periodic_orbits(
CASM::log());
574 std::vector<std::pair<std::string, ConfigEnumInput>> all_with_cluster_sites;
575 for (
auto &input_name_value_pair : config_enum_input) {
576 std::vector<ConfigEnumInput> with_cluster_sites;
578 std::back_inserter(with_cluster_sites));
581 for (
auto const &value : with_cluster_sites) {
582 std::stringstream ss;
583 ss <<
", cluster_sites=" << jsonParser{value.sites()};
584 std::string
name = input_name_value_pair.first + ss.str();
585 all_with_cluster_sites.emplace_back(
name, value);
588 config_enum_input = std::move(all_with_cluster_sites);
593 notstd::make_unique<std::vector<std::pair<std::string, ConfigEnumInput>>>(
594 std::move(config_enum_input));
596 if (parser.value->size() == 0) {
597 std::stringstream msg;
598 msg <<
"Error creating input states: No supercells or configurations.";
599 parser.error.insert(msg.str());
std::shared_ptr< Structure const > shared_prim
iterator end() const override
iterator find(const std::string &name_or_alias) const override
PrimClex is the top-level data structure for a CASM project.
bool is_string() const
Check if string.
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
std::set< Index > const & sites() const
Configuration const & configuration() const
std::string scelname(const Structure &prim, const Lattice &superlat)
Make supercell name name [deprecated].
T get(Args &&... args) const
Get data from json, using one of several alternatives.
ConfigIO::GenericConfigFormatter< jsonParser > config()
IdentitySymRepBuilder Identity()
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
Inserter select_cluster_sites(ConfigEnumInput const &reference_config_enum_input, std::vector< PrimPeriodicIntegralClusterOrbit > const &orbits, Inserter result)
GenericDatumFormatter< std::string, DataObject > name()
void from_json(ClexDescription &desc, const jsonParser &json)
T min(const T &A, const T &B)
std::string parse_ConfigEnumInput_desc()
A string describing the JSON format for parsing named ConfigEnumInput.
void report_and_throw_if_invalid(KwargsParser const &parser, Log &log, ErrorType error)
INDEX_TYPE Index
For long integer indexing:
void parse(InputParser< ConfigEnumOptions > &parser, std::string method_name, PrimClex const &primclex, DataFormatterDictionary< Configuration > const &dict)
T max(const T &A, const T &B)
bool valid() const
Return true if this and and all subparsers are valid.
std::set< std::string > error
static ReturnType from_json(const jsonParser &json)
Default from_json is equivalent to.