World Builder  1.1.0-pre
A geodynamic initial conditions generator
spherical.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 
26 
27 namespace WorldBuilder
28 {
29  namespace CoordinateSystems
30  {
32  {
33  this->world = world_;
34  }
35 
37  = default;
38 
39  void
40  Spherical::declare_entries(Parameters &prm, const std::string & /*unused*/)
41  {
42 
43  // Add depth method to the required parameters.
44  prm.declare_entry("", Types::Object({"depth method"}),
45  "A spherical coordinate system. The coordinates are (radius, longitude, latitude). "
46  "The radius is set in this plugin, the longitude extends at least from -360 to 360 degrees, "
47  "and the latitude extends from -90 to 90. It is required to choose a depth method. Please "
48  "see the manual for more information.");
49 
50 
51  prm.declare_entry("depth method",
52  Types::String("",std::vector<std::string>({"starting point", "begin segment","begin at end segment", "continuous"})),
53  R"(Which depth method to use in the spherical case. The available options are 'starting point', )"
54  R"('begin segment' and 'begin at end segment'. See the manual section on coordinate systems for )"
55  R"(more info.)");
56 
57  prm.declare_entry("radius",
58  Types::Double(6371000.),
59  R"(The radius of the sphere.)");
60 
61 
62  }
63 
64  void
66  {
67  prm.enter_subsection("coordinate system");
68  {
69  const std::string string_depth_method = prm.get<std::string>("depth method");
70  if (string_depth_method == "starting point")
72  else if (string_depth_method == "begin segment")
74  else if (string_depth_method == "begin at end segment")
76  //else if (string_depth_method == "continuous")
77  //used_depth_method = DepthMethod::continuous_angle_with_surface;
78  else
79  WBAssertThrow(true,"Option " << string_depth_method << " is not a valid depth method for spherical "
80  "coordinates. The available options are 'starting point', 'begin segment' and 'begin at end segment'. "
81  "The option 'continuous' is not yet available.");
82 
83  radius_sphere = prm.get<double>("radius");
84  }
85  prm.leave_subsection();
86  }
87 
88 
91  {
93  }
94 
95 
98  {
99  return used_depth_method;
100  }
101 
102 
103  std::array<double,3>
104  Spherical::cartesian_to_natural_coordinates(const std::array<double,3> &position) const
105  {
107  }
108 
109 
110  std::array<double,3>
111  Spherical::natural_to_cartesian_coordinates(const std::array<double,3> &position) const
112  {
114  }
115 
116  double
118  {
120  "Can not convert non spherical points through the spherical coordinate system.");
122  "Can not convert non spherical points through the spherical coordinate system.");
123  const double radius = point_1[0];
124  WBAssert((radius - point_2[0]) < std::numeric_limits<double>::epsilon() * std::max(1.0,radius), "The radius of point 1 is not the same as the radius of point 2.");
125 
126  // based on https://math.stackexchange.com/questions/1304169/distance-between-two-points-on-a-sphere
127  const Point<3> point_1_cart = Utilities::spherical_to_cartesian_coordinates(point_1.get_array());
128  const Point<3> point_2_cart = Utilities::spherical_to_cartesian_coordinates(point_2.get_array());
129 
130  return radius * std::acos(std::min(1.,std::max(0.,point_1_cart*point_2_cart/(radius*radius))));
131  }
132 
133 
134  double
136  {
137  return radius_sphere;
138  }
139 
144  } // namespace CoordinateSystems
145 } // namespace WorldBuilder
146 
#define WB_REGISTER_COORDINATE_SYSTEM(classname, name)
Definition: interface.h:168
std::array< double, 3 > cartesian_to_spherical_coordinates(const Point< 3 > &position)
Definition: utilities.cc:255
void parse_entries(Parameters &prm) override final
Definition: spherical.cc:65
Spherical(WorldBuilder::World *world)
Definition: spherical.cc:31
std::array< double, 3 > natural_to_cartesian_coordinates(const std::array< double, 3 > &position) const override final
Definition: spherical.cc:111
void enter_subsection(const std::string &name)
Definition: parameters.cc:1871
virtual double max_model_depth() const override final
Definition: spherical.cc:135
static void declare_entries(Parameters &prm, const std::string &parent_name="")
Definition: spherical.cc:40
Point< 3 > spherical_to_cartesian_coordinates(const std::array< double, 3 > &scoord)
Definition: utilities.cc:274
CoordinateSystem get_coordinate_system() const
Definition: point.h:403
const std::array< double, dim > & get_array() const
Definition: point.h:393
CoordinateSystem natural_coordinate_system() const override final
Definition: spherical.cc:90
#define WBAssert(condition, message)
Definition: assert.h:27
#define WBAssertThrow(condition, message)
Definition: assert.h:40
DepthMethod depth_method() const override final
Definition: spherical.cc:97
void declare_entry(const std::string &name, const Types::Interface &type, const std::string &documentation)
Definition: parameters.cc:197
double distance_between_points_at_same_depth(const Point< 3 > &point_1, const Point< 3 > &point_2) const override final
Definition: spherical.cc:117
T get(const std::string &name)
std::array< double, 3 > cartesian_to_natural_coordinates(const std::array< double, 3 > &position) const override final
Definition: spherical.cc:104