QMCPACK
SpaceGridInput.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2023 QMCPACK developers.
6 //
7 // File developed by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
8 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
9 // Peter W. Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
10 //
11 // Some code refactored from: QMCHamiltonians/SpaceGrid.cpp
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 #include "SpaceGridInput.h"
15 
16 #include <sstream>
17 #include <vector>
18 
19 #include "EstimatorInput.h"
21 
22 namespace qmcplusplus
23 {
24 
26 {
28  auto setIfInInput = LAMBDA_setIfInInput;
29  setIfInInput(label_, "label");
30  setIfInInput(grid_, "grid");
31  setIfInInput(p1_, "p1");
32  setIfInInput(p2_, "p2");
33  setIfInInput(scale_, "scale");
34 }
35 
37  const std::string& name,
38  std::istringstream& svalue)
39 {
40  // grid can only be an attribute for space grid axes.
41  if (name == "grid")
42  {
43  try
44  {
45  values_[name] = parseGridInput<Real>(svalue);
46  }
47  catch (const UniformCommunicateError& uce)
48  {
49  std::ostringstream msg;
50  msg << "SpaceGridAxisInputSection failed in custom stream handler with: " << uce.what()
51  << " a report of the current parse progress should be found above\n";
52  report();
53  throw UniformCommunicateError(msg.str());
54  }
55  }
56  else
57  throw std::runtime_error("bad name passed or custom setFromStream not implemented in derived class.");
58 }
59 
61 {
63  auto setIfInInput = LAMBDA_setIfInInput;
64  setIfInInput(p1_, "p1");
65  setIfInInput(p2_, "p2");
66  setIfInInput(fraction_, "fraction");
67 }
68 
70 {
72  auto setIfInInput = LAMBDA_setIfInInput;
73  setIfInInput(coord_form_, "coord");
74  // rip open the axes inputs we're guarateed they have the proper dimensionality already
75 
76  auto axes = input_section_.get<std::vector<std::any>>("axis");
77  checkAxes(axes);
78  for (int d = 0; d < OHMMS_DIM; d++)
79  {
80  auto* axis_input = std::any_cast<SpaceGridAxisInput>(&axes[d]);
81  axis_labels_[d] = axis_input->get_label();
82  axis_p1s_[d] = axis_input->get_p1();
83  axis_p2s_[d] = axis_input->get_p2();
84  axis_grids_[d] = axis_input->get_grid();
85  axis_scales_[d] = axis_input->get_scale();
86  }
87  checkGrids();
88  if (input_section_.has("origin"))
89  {
90  auto space_grid_origin = input_section_.get<SpaceGridOriginInput>("origin");
91  origin_p1_ = space_grid_origin.get_p1();
92  origin_p2_ = space_grid_origin.get_p2();
93  origin_fraction_ = space_grid_origin.get_fraction();
94  }
95 }
96 
97 void SpaceGridInput::checkAxes(std::vector<std::any>& axes)
98 {
99  auto& ax_labels = axes_label_sets.at(coord_form_);
100  for (auto& axis : axes)
101  {
102  auto* axis_input = std::any_cast<SpaceGridAxisInput>(&axis);
103  std::string axis_label = axis_input->get_input().template get<std::string>("label");
104  auto result = std::find(std::begin(ax_labels), std::end(ax_labels), axis_label);
105  if (result == std::end(ax_labels))
106  throw UniformCommunicateError(axis_label + " is not a valid label for coord form " +
107  input_section_.get<std::string>("coord"));
108  }
109 }
110 
112 {
113  //check that all axis grid values fall in the allowed intervals for the coord label
114  for (int d = 0; d < OHMMS_DIM; d++)
115  {
116  if (axis_labels_[d] == "r" || axis_labels_[d] == "phi" || axis_labels_[d] == "theta")
117  {
118  if (axis_grids_[d].umin < 0.0 || axis_grids_[d].umax > 1.0)
119  {
120  std::ostringstream error;
121  error << " grid values for " << axis_labels_[d] << " must fall in [0,1]" << std::endl;
122  error << " interval provided: [" << axis_grids_[d].umin << "," << axis_grids_[d].umax << "]" << std::endl;
123  throw UniformCommunicateError(error.str());
124  }
125  }
126  // all other legal labels {"x","y","z"} can be over -1.0 to 1.0
127  else if (axis_grids_[d].umin < -1.0 || axis_grids_[d].umax > 1.0)
128  {
129  std::ostringstream error;
130  error << " grid values for " << axis_labels_[d] << " must fall in [-1,1]" << std::endl;
131  error << " interval provided: [" << axis_grids_[d].umin << "," << axis_grids_[d].umax << "]" << std::endl;
132  throw UniformCommunicateError(error.str());
133  }
134  }
135 }
136 
137 
138 std::any SpaceGridInput::SpaceGridInputSection::assignAnyEnum(const std::string& name) const
139 {
140  return lookupAnyEnum(name, get<std::string>(name), lookup_input_enum_value);
141 }
142 
143 std::any makeSpaceGridInput(xmlNodePtr cur, std::string& value_label)
144 {
145  SpaceGridInput sgi{cur};
146  value_label = "spacegrid";
147  return sgi;
148 }
149 
151 {
152  auto axes = std::any_cast<std::vector<std::any>>(values_["axis"]);
153  static_assert(std::is_same<decltype(axes), std::vector<std::any>>::value);
154  auto axis_count = axes.size();
155  if (axis_count != OHMMS_DIM)
156  {
157  std::ostringstream error;
158  error << "SpaceGrid input must contain " << OHMMS_DIM << " axes, " << axis_count << " found!";
159  throw UniformCommunicateError(error.str());
160  }
161 }
162 
163 } // namespace qmcplusplus
std::array< std::string, OHMMS_DIM > axis_labels_
void checkAxes(std::vector< std::any > &axes)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
SpaceGridInputSection input_section_
void setFromStreamCustom(const std::string &ename, const std::string &name, std::istringstream &svalue) override
Derived class can overrides this to do custom parsing of the element values for Custom elements These...
static const std::unordered_map< std::string, std::any > lookup_input_enum_value
std::array< std::string, OHMMS_DIM > axis_p1s_
std::any makeSpaceGridInput(xmlNodePtr cur, std::string &value_label)
factory function for a SpaceGridInput
bool is_same(const xmlChar *a, const char *b)
#define OHMMS_DIM
Definition: config.h:64
const SpaceGridAxisInputSection & get_input()
void error(char const *m)
Definition: Standard.h:204
std::array< AxisGrid< Real >, OHMMS_DIM > axis_grids_
#define LAMBDA_setIfInInput
If tag is present in input_secution set its variable.
std::any assignAnyEnum(const std::string &name) const override
Derived class overrides this to get proper assignment of scoped enum values.
This a subclass for runtime errors that will occur on all ranks.
void readXML(xmlNodePtr cur)
Read variable values (initialize) from XML input, call checkValid.
std::array< std::string, OHMMS_DIM > axis_p2s_
static const std::unordered_map< CoordForm, LabelSet > axes_label_sets
void checkParticularValidity() override
Do validation for a particular subtype of InputSection Called by check_valid.
std::array< Real, OHMMS_DIM > axis_scales_
T get(const std::string &name) const
Definition: InputSection.h:92
bool has(const std::string &name) const
Definition: InputSection.h:87