13 namespace ClusterSpecs_json_io_impl {
29 template <
typename SpecsType>
32 auto specs_it = parser.
self.
find(
"orbit_branch_specs");
33 if (specs_it == parser.
self.
end() || specs_it->is_null()) {
34 return std::vector<double>({0.});
36 std::vector<double> result({0.});
38 if (!specs_it->is_obj()) {
39 fs::path path{
"orbit_branch_specs"};
40 std::stringstream msg;
41 msg <<
"Expected a JSON object";
46 auto update_result = [&](
int branch,
double value) {
47 while (branch >= result.size()) {
48 result.push_back(0.0);
50 result[branch] = value;
53 for (
auto it = specs_it->begin(); it != specs_it->end(); ++it) {
56 fs::path path{
"orbit_branch_specs"};
57 std::stringstream msg;
58 msg <<
"Expected JSON object containing '" << attrname
59 <<
"' (double, default=0.).";
63 auto attr_it = it->find(attrname);
64 if (attr_it != it->end()) {
65 value = attr_it->template get<double>();
67 update_result(std::stoi(it.name()), value);
74 for (
const auto &op : grp) {
81 std::set<Index> prim_factor_group_indices;
82 for (
auto const &permute_it : grp) {
83 prim_factor_group_indices.insert(permute_it.prim_factor_group_index());
86 json = prim_factor_group_indices;
91 auto it = super_group.begin();
92 auto end = super_group.end();
93 for (; it != end; ++it) {
94 if (it->index() == op.
index()) {
102 const std::set<Index> &indices) {
103 auto result = notstd::make_unique<SymGroup>();
104 result->set_lattice(super_group.
lattice());
105 for (
SymOp const &op : super_group) {
106 if (indices.count(op.index())) {
107 result->push_back(op);
111 if ((*result)[0].index() != 0) {
112 throw std::runtime_error(
113 "Error in group_from_indices: First element is not identity.");
115 if (!result->is_group(super_group.
lattice().
tol())) {
116 throw std::runtime_error(
"Error in local_group_from_indices: Not a group.");
121 template <
typename SymCompareType>
123 const SymGroup &super_group,
const std::set<Index> &indices,
125 const SymCompareType &sym_compare) {
128 auto result = notstd::make_unique<SymGroup>();
129 result->set_lattice(super_group.
lattice());
130 for (
SymOp const &op : super_group) {
131 if (indices.count(op.index())) {
137 if (sym_compare.equal(
138 e, sym_compare.prepare(sym_compare.copy_apply(op, e)))) {
139 result->push_back(sym_compare.spatial_transform() * op);
141 throw std::runtime_error(
142 "Error in local_group_from_indices: Phenomenal cluster sites are "
148 if ((*result)[0].index() != 0) {
149 throw std::runtime_error(
150 "Error in local_group_from_indices: First element is not identity.");
152 if (!result->is_group(sym_compare.tol())) {
153 throw std::runtime_error(
"Error in local_group_from_indices: Not a group.");
160 const std::shared_ptr<const Structure> &
shared_prim,
162 auto generating_group_indices =
163 parser.
optional<std::set<Index>>(
"generating_group");
164 if (generating_group_indices) {
167 }
catch (std::exception &e) {
168 parser.
error.insert(std::string(
"Error parsing generating_group:") +
170 return std::unique_ptr<SymGroup>{};
177 template <
typename SymCompareType>
180 const std::shared_ptr<const Structure> &
shared_prim,
182 const SymCompareType &sym_compare) {
183 std::set<Index> generating_group_indices;
184 parser.
require(generating_group_indices,
"generating_group");
185 if (!parser.
valid()) {
186 return std::unique_ptr<SymGroup>();
190 phenomenal, sym_compare);
191 }
catch (std::exception &e) {
192 parser.
error.insert(std::string(
"Error parsing generating_group:") +
195 return std::unique_ptr<SymGroup>();
222 const std::shared_ptr<const Structure> &
shared_prim,
224 using namespace ClusterSpecs_json_io_impl;
227 auto generating_group_ptr =
229 if (!generating_group_ptr) {
237 std::vector<IntegralClusterOrbitGenerator> default_custom_generators{};
238 auto custom_generators_parser =
239 parser.
subparse_else<std::vector<IntegralClusterOrbitGenerator>>(
240 "orbit_specs", default_custom_generators, *
shared_prim);
242 if (!parser.
valid()) {
245 parser.
value = notstd::make_unique<PeriodicMaxLengthClusterSpecs>(
247 *custom_generators_parser->value);
281 const std::shared_ptr<const Structure> &
shared_prim,
283 using namespace ClusterSpecs_json_io_impl;
286 auto phenomenal_subparser_ptr =
288 if (!phenomenal_subparser_ptr->valid()) {
297 parser,
shared_prim, phenomenal, super_group, sym_compare);
304 std::vector<IntegralClusterOrbitGenerator> default_custom_generators{};
305 auto custom_generators_parser =
306 parser.
subparse_else<std::vector<IntegralClusterOrbitGenerator>>(
307 "orbit_specs", default_custom_generators, *
shared_prim);
310 bool include_phenomenal_sites =
false;
312 if (!parser.
valid()) {
315 parser.
value = notstd::make_unique<LocalMaxLengthClusterSpecs>(
317 max_length, cutoff_radius, include_phenomenal_sites,
318 *custom_generators_parser->value);
328 const std::shared_ptr<const Structure> &
shared_prim) {
514 const std::shared_ptr<const Structure> &
shared_prim,
517 parser.
require(method,
"method");
518 if (method.empty()) {
523 if (method ==
"periodic_max_length") {
526 if (subparser->value) {
527 parser.
value = std::move(subparser->value);
529 }
else if (method ==
"local_max_length") {
532 if (subparser->value) {
533 parser.
value = std::move(subparser->value);
536 parser.
error.insert(
"Error: unknown cluster_specs method '" + method +
541 namespace ClusterSpecs_json_io_impl {
544 const std::string &attrname,
547 for (
int b = 0; b < attr.size(); ++b) {
556 json[
"method"] = cspecs.
name();
559 using namespace ClusterSpecs_json_io_impl;
572 json[
"method"] = cspecs.
name();
576 using namespace ClusterSpecs_json_io_impl;
599 throw std::runtime_error(
600 std::string(
"Error converting ClusterSpecs to JSON:") +
601 " cannot convert method: '" + cspecs.
name() +
"'");
std::shared_ptr< Structure const > shared_prim
std::string name() const
This is the orbit generation method name.
Parameters most commonly used for local orbit generation.
static std::string const method_name
std::vector< double > max_length
std::vector< IntegralClusterOrbitGenerator > custom_generators
Specifies particular clusters that should be used to generate orbits.
IntegralCluster phenomenal
Phenomenal cluster, used to find local neighborhood.
SymGroup generating_group
std::vector< double > cutoff_radius
static std::string const method_name
SymGroup generating_group
std::vector< double > max_length
std::vector< IntegralClusterOrbitGenerator > custom_generators
Specifies particular clusters that should be used to generate orbits.
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
const Lattice & lattice() const
Lattice used for periodic comparisons (for instance, to generate multiplcation table)
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
iterator end()
Returns iterator to end of JSON object or JSON array.
iterator find(const std::string &name)
Return iterator to JSON object value with 'name'.
jsonParser & put_array()
Puts new empty JSON array.
std::string to_string(ENUM val)
Return string representation of enum class.
jsonParser & push_back(const T &value, Args &&... args)
std::unique_ptr< SymGroup > local_group_from_indices(const SymGroup &super_group, const std::set< Index > &indices, const IntegralCluster &phenomenal, const SymCompareType &sym_compare)
std::unique_ptr< SymGroup > group_from_indices(const SymGroup &super_group, const std::set< Index > &indices)
void write_group_indices(const SymGroup &grp, jsonParser &json)
std::vector< SymOp >::const_iterator find_by_master_group_index(const SymOp &op, const SymGroup &super_group)
std::vector< double > parse_orbit_branch_specs_attr(InputParser< SpecsType > &parser, const std::string &attrname)
std::unique_ptr< SymGroup > parse_generating_group(InputParser< PeriodicMaxLengthClusterSpecs > &parser, const std::shared_ptr< const Structure > &shared_prim, const SymGroup &super_group)
jsonParser & orbit_branch_specs_attr_to_json(std::vector< double > attr, const std::string &attrname, jsonParser &json)
std::unique_ptr< SymGroup > parse_local_generating_group(InputParser< LocalMaxLengthClusterSpecs > &parser, const std::shared_ptr< const Structure > &shared_prim, const IntegralCluster &phenomenal, const SymGroup &super_group, const SymCompareType &sym_compare)
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
SiteFilterFunction dof_sites_filter(const std::vector< DoFKey > &dofs={})
Generate clusters using Site with specified DoF.
void parse(InputParser< ConfigEnumOptions > &parser, std::string method_name, PrimClex const &primclex, DataFormatterDictionary< Configuration > const &dict)
std::unique_ptr< T > clone(const T &obj)
bool valid() const
Return true if this and and all subparsers are valid.
void insert_error(fs::path option, std::string message)
Insert a subparser at location option with a single error message
std::set< std::string > error