World Builder  1.1.0-pre
A geodynamic initial conditions generator
interface.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2018-2024 by the authors of the World Builder code.
3 
4  This file is part of the World Builder.
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19 
21 
22 #include <algorithm>
23 
27 #include "world_builder/world.h"
28 
29 namespace WorldBuilder
30 {
31  using namespace Utilities;
32 
33  namespace Features
34  {
35  namespace Internal
36  {
37 
38 
39 
43  static InterpolationType string_to_interpolation_type (const std::string &string)
44  {
45  if (string == "continuous monotone spline")
46  {
48  }
49 
50  WBAssertThrow(false,
51  "You provided an interpolation type which is not supported: " << string
52  << "This may be due to all options besides continuous monotone spline have been "
53  << "removed since version 0.5. It is best to remove the interpolation variable "
54  << "from you input file as it may be removed in future versions.");
55 
57  }
58  } // namespace Internal
59 
60  Interface::Interface()
61  = default;
62 
63  Interface::~Interface ()
64  = default;
65 
66  void
67  Interface::declare_entries(Parameters &prm, const std::string &parent_name, const std::vector<std::string> &required_entries)
68  {
69 
70  {
71  using namespace rapidjson;
72  Document &declarations = prm.declarations;
73 
74  prm.enter_subsection("defaultSnippets");
75  const std::string path = prm.get_full_json_path();
76 
77  unsigned int idx = 0;
78  for (auto &it : get_snippet_map())
79  {
80  std::string item = path + "/"+std::to_string(idx);
81 
82  Pointer((item).c_str()).Set(declarations, "object");
83  Pointer((item+"/label").c_str()).Set(declarations,("add a '" + it.first + "'").c_str());
84  prm.enter_subsection(std::to_string(idx).c_str());
85  it.second(prm);
86  prm.leave_subsection();
87 
88  ++idx;
89  }
90 
91  prm.leave_subsection();
92  }
93 
94  unsigned int counter = 0;
95  for (auto &it : get_declare_map())
96  {
97  prm.enter_subsection("oneOf");
98  {
99  prm.enter_subsection(std::to_string(counter));
100  {
101 
102  prm.enter_subsection("properties");
103  {
104  prm.declare_entry("", Types::Object(required_entries), "feature object");
105 
106  prm.declare_entry("model", Types::String("",it.first),
107  "The model name of the feature determining its type.");
108  prm.declare_entry("name", Types::String(""),
109  "The name which the user has given to the feature. "
110  "This is mostly used for documentation purposes, and should in most cases be unique, "
111  "although this is not enforced.");
112  prm.declare_entry("tag", Types::String(""),
113  "A tag which can be given to a feature. This is meant to categorize different features. "
114  "If the tag is not provided or empty, it is set to the model name.");
115  prm.declare_entry("coordinates", Types::Array(Types::Point<2>(), 1),
116  "An array of 2d Points representing an array of coordinates where the feature is located.");
117 
118  prm.declare_entry("interpolation",Types::String("global"),
119  "What type of interpolation should be used to enforce the minimum points per "
120  "distance parameter. Options are 'global' and "
121  "'continuous monotone spline' interpolation. If this "
122  "value is set to global, the global value for interpolation is used. "
123  "This option is deprecated and will be removed in a future release.");
124  WBAssert(it.second != NULL, "No declare entries given.");
125  it.second(prm, parent_name, {});
126  }
127  prm.leave_subsection();
128  }
129  prm.leave_subsection();
130  }
131  prm.leave_subsection();
132 
133  counter++;
134 
135  }
136  }
137 
138 
139  void
140  Interface::get_coordinates(const std::string & /*unused*/,
141  Parameters &prm,
142  const CoordinateSystem coordinate_system)
143  {
144  coordinates = prm.get_vector<Point<2> >("coordinates");
145  if (coordinate_system == CoordinateSystem::spherical)
146  std::transform(coordinates.begin(),coordinates.end(), coordinates.begin(),
147  [](const WorldBuilder::Point<2> &p) -> WorldBuilder::Point<2> { return p *Consts::PI / 180.0;});
148 
149 
150  // If global is given, we use the global interpolation setting, otherwise use the provided value.
151  const std::string interpolation_type_string = prm.get<std::string>("interpolation") == "global" ? this->world->interpolation : prm.get<std::string>("interpolation");
152  interpolation_type = WorldBuilder::Features::Internal::string_to_interpolation_type(interpolation_type_string);
153 
154  original_number_of_coordinates = coordinates.size();
155 
159  "For interpolation, linear and monotone spline are the only allowed values. "
160  << "You provided " << interpolation_type_string << '.');
161 
162  bezier_curve = Objects::BezierCurve(coordinates);
163 
164  }
165 
166 
167  void
168  Interface::registerType(const std::string &name,
169  void ( *declare_entries)(Parameters &, const std::string &,const std::vector<std::string> &),
170  void ( *make_snippet)(Parameters &),
171  ObjectFactory *factory)
172  {
173  get_factory_map()[name] = factory;
174  get_declare_map()[name] = declare_entries;
175  get_snippet_map()[name] = make_snippet;
176  }
177 
178  std::unique_ptr<Interface>
179  Interface::create(const std::string &name, WorldBuilder::World *world)
180  {
181  std::string lower_case_name;
182  std::transform(name.begin(),
183  name.end(),
184  std::back_inserter(lower_case_name),
185  ::tolower);;
186 
187  // Have a nice assert message to check whether a plugin exists in the case
188  // of a debug compilation.
189  WBAssertThrow(get_factory_map().find(lower_case_name) != get_factory_map().end(),
190  "Internal error: Plugin with name '" << lower_case_name << "' is not found. "
191  "The size of factories is " << get_factory_map().size() << '.');
192 
193  // Using at() because the [] will just insert values
194  // which is undesirable in this case. An exception is
195  // thrown when the name is not present.
196  return get_factory_map().at(lower_case_name)->create(world);
197  }
198 
200  Interface::distance_to_feature_plane(const Point<3> & /*unused*/,
201  const Objects::NaturalCoordinate & /*unused*/,
202  const double /*unused*/) const
203  {
204  WBAssertThrow(false, "The distance_to_feature_plane is not yet implemented for the desinated object");
205  }
206 
207  } // namespace Features
208 } // namespace WorldBuilder
209 
Class for circle line/spline, including interpolation on it.
Definition: bezier_curve.h:37
void enter_subsection(const std::string &name)
Definition: parameters.cc:1871
#define WBAssert(condition, message)
Definition: assert.h:27
std::string get_full_json_path(size_t max_size=std::numeric_limits< size_t >::max()) const
Definition: parameters.cc:1933
#define WBAssertThrow(condition, message)
Definition: assert.h:40
constexpr double PI
Definition: consts.h:30
void declare_entry(const std::string &name, const Types::Interface &type, const std::string &documentation)
Definition: parameters.cc:197
std::vector< T > get_vector(const std::string &name)
T get(const std::string &name)
rapidjson::Document declarations
Definition: parameters.h:248