World Builder  0.1.0-pre
A geodyanmic initial conditions generator
world.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2018 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 
20 #include <sstream>
21 
22 
23 #include <world_builder/world.h>
25 #include <world_builder/assert.h>
26 #include <world_builder/point.h>
27 #include <world_builder/nan.h>
32 
33 
34 namespace WorldBuilder
35 {
36 
37  using namespace Utilities;
38 
39  World::World(std::string filename)
40  :
41  dim(NaN::ISNAN),
42  parameters(filename,*this)
43  {
45  }
46 
48  {}
49 
51  {
55  prm.load_entry("Potential mantle temperature", false,
56  Types::Double(1600,"The potential temperature of the mantle at the surface in Kelvin"));
57  prm.load_entry("Thermal expansion coefficient alpha", false,
58  Types::Double(3.5e-5,"The thermal expansion coefficient alpha. TODO: expand add units"));
59  prm.load_entry("specific heat Cp", false, Types::Double(1250,"The specific heat Cp. TODO: expand and add units"));
60 
64  prm.load_entry("Surface rotation angle", false,
65  Types::Double(0,"The angle with which the model should be rotated around the Surface rotation point."));
66  prm.load_entry("Surface rotation point", false,
67  Types::Point<2>(Point<2>(0,0), "The point where should be rotated around."));
68 
72  prm.load_entry("Coordinate system", false, Types::CoordinateSystem("cartesian","This determines the coordinate system"));
73 
74 
75  bool set = prm.load_entry("Cross section", false,
77  Types::Point<2>(Point<2>(0,0),"A point in the cross section."),
78  "This is an array of two points along where the cross section is taken"));
79 
80  if (set)
81  {
82  dim = 2;
83  std::vector<const Types::Point<2>* > cross_section = prm.get_array<const Types::Point<2> >("Cross section");
84 
85  WBAssertThrow(cross_section.size() == 2, "The cross section should contain two points, but it contains "
86  << cross_section.size() << " points.");
87 
91  Point<2> surface_coord_conversions = (*cross_section[0]-*cross_section[1]);
92  surface_coord_conversions *= 1/(surface_coord_conversions.norm());
93  prm.set_entry("Surface coordinate conversions",
94  Types::Point<2>(surface_coord_conversions, surface_coord_conversions, "An internal value which is precomputed."));
95  }
96  else
97  {
98  dim = 3;
99  }
100 
101  prm.load_entry("Surface objects", true, Types::List(
102  Types::Feature("These are the features"), "A list of features."));
103 
104  }
105 
106  double
107  World::temperature(const std::array<double,2> &point, const double depth, const double gravity_norm) const
108  {
109  // turn it into a 3d coordinate and call the 3d temperature function
110  WBAssertThrow(dim == 2, "This function can only be called when the cross section "
111  "variable in the world builder file has been set. Dim is "
112  << dim << ".");
113 
114  // Todo: merge this into one line
115  const Types::Array &cross_section_natural = parameters.get_array("Cross section");
116 
117  WBAssert(cross_section_natural.inner_type_index.size() == 2, "Internal error: Cross section natural should contain two points, but it contains " << cross_section_natural.inner_type_index.size() << " points.");
118 
119  std::vector<Types::Point<2> > cross_section;
120  for (unsigned int i = 0; i < cross_section_natural.inner_type_index.size(); ++i)
121  cross_section.push_back(parameters.vector_point_2d[cross_section_natural.inner_type_index[i]]);
122 
123  WBAssert(cross_section.size() == 2, "Internal error: Cross section should contain two points, but it contains " << cross_section.size() << " points.");
124 
125  const WorldBuilder::Point<2> &surface_coord_conversions = this->parameters.get_point<2>("Surface coordinate conversions");
126 
127  Point<3> coord_3d(cross_section[0][0] + point[0] * surface_coord_conversions[0],
128  cross_section[0][1] + point[0] * surface_coord_conversions[1],
129  point[1]);
130 
131  return temperature(coord_3d.get_array(), depth, gravity_norm);
132  }
133 
134  double
135  World::temperature(const std::array<double,3> &point_, const double depth, const double gravity_norm) const
136  {
137  Point<3> point(point_);
138 
139  double temperature = this->parameters.get_double("Potential mantle temperature") +
140  (((this->parameters.get_double("Potential mantle temperature") * this->parameters.get_double("Thermal expansion coefficient alpha") * gravity_norm) /
141  this->parameters.get_double("specific heat Cp")) * 1000.0) * ((depth) / 1000.0);
142 
143 
144  for (std::vector<std::unique_ptr<Features::Interface> >::const_iterator it = parameters.features.begin(); it != parameters.features.end(); ++it)
145  {
146  temperature = (*it)->temperature(point,depth,gravity_norm,temperature);
147  }
148 
149  return temperature;
150  }
151 
152  bool
153  World::composition(const std::array<double,2> &point, const double depth, const unsigned int composition_number) const
154  {
155  // turn it into a 3d coordinate and call the 3d temperature function
156  WBAssertThrow(dim == 2, "This function can only be called when the cross section "
157  "variable in the world builder file has been set. Dim is "
158  << dim << ".");
159 
160  // Todo: merge this into one line
161  const Types::Array &cross_section_natural = this->parameters.get_array("Cross section");
162  std::vector<Types::Point<2> > cross_section;
163  for (unsigned int i = 0; i < cross_section_natural.inner_type_index.size(); ++i)
164  cross_section.push_back(this->parameters.vector_point_2d[cross_section_natural.inner_type_index[i]]);
165 
166  WBAssert(cross_section.size() == 2, "Internal error: Cross section should contain two points, but it contains "
167  << cross_section.size() << " points.");
168 
169  const WorldBuilder::Point<2> &surface_coord_conversions = this->parameters.get_point<2>("Surface coordinate conversions");
170 
171  Point<3> coord_3d(cross_section[0][0] + point[0] * surface_coord_conversions[0],
172  cross_section[0][1] + point[0] * surface_coord_conversions[1],
173  point[1]);
174 
175  return composition(coord_3d.get_array(), depth, composition_number);
176  }
177 
178  bool
179  World::composition(const std::array<double,3> &point_, const double depth, const unsigned int composition_number) const
180  {
181  Point<3> point(point_);
182  double composition = 0;
183  for (std::vector<std::unique_ptr<Features::Interface> >::const_iterator it = parameters.features.begin(); it != parameters.features.end(); ++it)
184  {
185  composition = (*it)->composition(point,depth,composition_number, composition);
186  }
187 
188  return composition;
189  }
190 
191  /*WorldBuilder::CoordinateSystems::Interface &
192  World::get_coordinate_system() const
193  {
194  return *coordinate_system;
195  }*/
196 }
197 
void declare_and_parse(Parameters &parameters)
Definition: world.cc:50
bool composition(const std::array< double, 2 > &point, const double depth, const unsigned int composition_number) const
Definition: world.cc:153
double temperature(const std::array< double, 2 > &point, const double depth, const double gravity_norm) const
Definition: world.cc:107
std::vector< unsigned int > inner_type_index
Definition: array.h:113
World(std::string filename)
Definition: world.cc:39
const Types::Array & get_array(const std::string &name) const
Definition: parameters.cc:551
const std::array< double, dim > & get_array() const
Definition: point.cc:201
#define WBAssert(condition, message)
Definition: assert.h:28
std::vector< Types::Point< 2 > > vector_point_2d
Definition: parameters.h:294
bool load_entry(const std::string &name, const bool required, const Types::Interface &type)
Definition: parameters.cc:56
#define WBAssertThrow(condition, message)
Definition: assert.h:41
Point< dim > get_point(const std::string &name) const
std::vector< std::unique_ptr< WorldBuilder::Features::Interface > > features
Definition: parameters.h:313
const double ISNAN
Definition: nan.h:34
Parameters parameters
Definition: world.h:72
bool set_entry(const std::string &name, const Types::Interface &type)
Definition: parameters.cc:387
double get_double(const std::string &name) const
Definition: parameters.cc:516