25 void _add_homogeneous_mode_info(jsonParser &json, DoFSpace
const &dofspace) {
26 jsonParser &irreps_json = json[
"irreducible_representations"];
31 auto print_string = [&](std::vector<Index>
const &indices) {
32 std::vector<std::string> string_of_indices;
33 for (
auto &i : indices) {
35 string_of_indices.push_back(
s);
37 return string_of_indices;
40 VectorSpaceMixingInfo mixing_info(dofspace.basis(), homogeneous_mode_space,
42 irreps_json[
"adapted_axes_which_are_not_homogeneous_modes"] =
43 print_string(mixing_info.axes_not_in_subspace);
44 irreps_json[
"adapted_axes_mixed_with_homogeneous_modes"] =
45 print_string(mixing_info.axes_mixed_with_subspace);
46 irreps_json[
"adapted_axes_which_are_homogeneous_modes"] =
47 print_string(mixing_info.axes_in_subspace);
52 std::shared_ptr<Structure const>
const &
shared_prim) {
57 std::optional<std::string>
const &identifier,
58 std::optional<ConfigEnumInput>
const &input_state,
59 std::optional<VectorSpaceSymReport>
const &sym_report) {
60 json[
"dof"] = dofspace.
dof_key();
61 json[
"transformation_matrix_to_supercell"] =
63 json[
"sites"] = dofspace.
sites();
64 json[
"basis"] = dofspace.
basis().transpose();
69 if (identifier.has_value()) {
70 json[
"identifier"] = identifier;
72 if (input_state.has_value()) {
73 json[
"state"] = input_state;
75 if (sym_report.has_value()) {
78 _add_homogeneous_mode_info(json, dofspace);
86 std::optional<std::string>
const &identifier,
87 std::optional<ConfigEnumInput>
const &input_state,
88 std::optional<SymRepTools_v2::VectorSpaceSymReport>
const &sym_report) {
89 json[
"dof"] = dofspace.
dof_key();
90 json[
"transformation_matrix_to_supercell"] =
92 json[
"sites"] = dofspace.
sites();
93 json[
"basis"] = dofspace.
basis().transpose();
98 if (identifier.has_value()) {
99 json[
"identifier"] = identifier;
101 if (input_state.has_value()) {
102 json[
"state"] = input_state;
104 if (sym_report.has_value()) {
107 _add_homogeneous_mode_info(json, dofspace);
115 std::shared_ptr<Structure const>
const &
shared_prim) {
118 std::runtime_error error_if_invalid{
"Error reading DoFSpace from JSON"};
121 return std::move(*parser.value);
126 std::shared_ptr<Structure const>
const &
shared_prim) {
129 std::runtime_error error_if_invalid{
"Error reading DoFSpace from JSON"};
132 return std::move(parser.value);
136 std::shared_ptr<Structure const>
const &
shared_prim) {
138 parser.
require(dof_key,
"dof");
142 "transformation_matrix_to_supercell");
144 std::optional<std::set<Index>> sites;
149 std::optional<Eigen::MatrixXd> basis = tmp.transpose();
151 if (parser.
valid()) {
152 parser.
value = notstd::make_unique<DoFSpace>(
164 void _enforce_num(InputParser<AxesCounterParams> &parser,
double &inc,
165 double &
max,
double min,
int num) {
167 parser.insert_error(
"num",
"Error: 'num' must be >= 1.");
168 }
else if (num == 1) {
172 inc = (
max -
min) / (num - 1);
178 void _parse_scalar_input(InputParser<AxesCounterParams> &parser) {
179 AxesCounterParams ¶ms = *parser.value;
180 params.scalar_input =
true;
182 parser.optional_else(params.min_scalar,
"min", 0.);
183 parser.require(params.max_scalar,
"max");
185 if (parser.self.contains(
"increment") == parser.self.contains(
"num")) {
186 parser.error.insert(
"Error: require one of 'increment' or 'num'.");
189 if (parser.self.contains(
"increment")) {
190 parser.optional(params.inc_scalar,
"increment");
195 parser.optional(num_scalar,
"num");
196 _enforce_num(parser, params.inc_scalar, params.max_scalar,
197 params.min_scalar, num_scalar);
202 void _parse_vector_input(InputParser<AxesCounterParams> &parser) {
203 AxesCounterParams ¶ms = *parser.value;
204 int dim = params.axes.cols();
205 params.scalar_input =
false;
209 parser.optional_else(params.min_vector,
"min", default_min);
210 if (params.min_vector.size() != dim) {
211 parser.insert_error(
"min",
"Error: 'min' size != axes dimension");
215 parser.require(params.max_vector,
"max");
216 if (params.max_vector.size() != dim) {
217 parser.insert_error(
"max",
"Error: 'max' size != axes dimension");
221 if (parser.self.contains(
"increment") == parser.self.contains(
"num")) {
222 parser.error.insert(
"Error: require one of 'increment' or 'num'.");
225 if (parser.self.contains(
"increment")) {
226 parser.optional(params.inc_vector,
"increment");
227 if (params.inc_vector.size() != dim) {
228 parser.insert_error(
"increment",
229 "Error: 'increment' size != axes dimension");
234 Eigen::VectorXi num_vector;
235 parser.optional(num_vector,
"num");
236 if (num_vector.size() != dim) {
237 parser.insert_error(
"num",
"Error: 'num' size != axes dimension");
239 for (
int i = 0; i < num_vector.size(); ++i) {
240 _enforce_num(parser, params.inc_vector[i], params.max_vector[i],
241 params.min_vector[i], num_vector[i]);
268 if (parser.
value ==
nullptr) {
269 throw std::runtime_error(
"Unknown AxesCounterParams parsing error");
275 parser.
insert_error(
"max",
"Error: missing required parameter 'max'.");
278 _parse_scalar_input(parser);
280 _parse_vector_input(parser);
282 std::stringstream msg;
283 msg <<
"Error: Parameter 'max' must be a number, or an "
284 "array of numbers matching the 'axes' dimension.";
333 Index dof_space_dimension) {
334 if (parser.
value ==
nullptr) {
335 throw std::runtime_error(
"Unknown AxesCounterParams parsing error");
339 Eigen::MatrixXd::Zero(dof_space_dimension, dof_space_dimension);
341 std::set<Index> found;
342 for (
Index i = 0; i < dof_space_dimension; ++i) {
343 std::string axis_name =
347 if (subparser->value !=
nullptr) {
348 if (subparser->value->size() != dof_space_dimension) {
349 std::stringstream msg;
350 msg <<
"Error reading axis vector '" << axis_name
351 <<
"': expected size=" << dof_space_dimension
352 <<
" found size=" << subparser->value->size();
353 subparser->error.insert(msg.str());
355 inaxes.col(found.size()) = *subparser->value;
361 Index subspace_dimension = found.size();
362 parser.
value->axes = inaxes.leftCols(subspace_dimension);
368 Index dof_space_dimension) {
369 if (parser.
value ==
nullptr) {
370 throw std::runtime_error(
"Unknown AxesCounterParams parsing error");
375 if (!subparser->valid()) {
379 axes = subparser->value->transpose();
382 if (axes.rows() != dof_space_dimension) {
385 std::stringstream msg;
386 msg <<
"Number of columns of 'axes' must be equal to site DoF space "
388 << dof_space_dimension <<
"). Size as parsed: " << axes.rows();
389 subparser->error.insert(msg.str());
391 if (axes.cols() > dof_space_dimension) {
393 std::stringstream msg;
394 msg <<
"Number of coordinate axes (number of rows of 'axes') must be less "
396 "site DoF space dimension ("
397 << dof_space_dimension <<
"). Number of axes parsed: " << axes.cols();
398 subparser->error.insert(msg.str());
417 Index dof_space_dimension) {
418 if (parser.
value ==
nullptr) {
430 std::stringstream msg;
431 msg <<
"The 'axes' must be a JSON object of axis vectors (named 'q1', "
432 "'q2', etc.), or a row-vector matrix";
433 parser.
error.insert(msg.str());
440 parser.
value = notstd::make_unique<AxesCounterParams>();
443 if (!parser.
valid()) {
444 parser.
value.reset();
std::set< std::string > & s
std::shared_ptr< Structure const > shared_prim
Eigen::MatrixXd const & basis() const
std::optional< std::vector< Index > > const & axis_site_index() const
bool includes_all_sites() const
True, if local DoF space with all sites in the supercell included.
std::optional< Eigen::Matrix3l > const & transformation_matrix_to_super() const
Specifies the supercell for a local DoF space. Has value for local DoF.
std::optional< std::vector< Index > > const & axis_dof_component() const
std::optional< std::set< Index > > const & sites() const
The sites included in a local DoF space. Has value for local DoF.
std::vector< std::string > const & axis_glossary() const
Names the DoF corresponding to each dimension (row) of the basis.
DoFKey const & dof_key() const
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
bool is_array() const
Check if array type.
bool is_number() const
Check if number type (including int)
bool is_obj() const
Check if object type.
IdentitySymRepBuilder Identity()
void parse_dof_space_axes(InputParser< AxesCounterParams > &parser, Index dof_space_dimension)
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
void parse_axes_from_object(InputParser< AxesCounterParams > &parser, Index dof_space_dimension)
std::string to_sequential_string(Index i, Index max_i, char prepend_char='0')
void parse_axes_counter_range(InputParser< AxesCounterParams > &parser)
Eigen::MatrixXd make_homogeneous_mode_space(DoFSpace const &dof_space)
Make the homogeneous mode space of a local DoFSpace.
void from_json(ClexDescription &desc, const jsonParser &json)
T min(const T &A, const T &B)
void parse_axes_from_array(InputParser< AxesCounterParams > &parser, Index dof_space_dimension)
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.
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
static ReturnType from_json(const jsonParser &json)
Default from_json is equivalent to.
static std::unique_ptr< ValueType > make_from_json(const jsonParser &json)
Default make_from_json is equivalent to.