World Builder  1.1.0-pre
A geodynamic initial conditions generator
adiabatic.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 
23 #include "world_builder/nan.h"
29 #include "world_builder/world.h"
30 
31 
32 namespace WorldBuilder
33 {
34  using namespace Utilities;
35 
36  namespace Features
37  {
38  using namespace FeatureUtilities;
39  namespace MantleLayerModels
40  {
41  namespace Temperature
42  {
43  Adiabatic::Adiabatic(WorldBuilder::World *world_)
44  :
45  min_depth(NaN::DSNAN),
46  max_depth(NaN::DSNAN),
47  potential_mantle_temperature(NaN::DSNAN),
48  thermal_expansion_coefficient(NaN::DSNAN),
49  specific_heat(NaN::DSNAN),
50  operation(Operations::REPLACE)
51  {
52  this->world = world_;
53  this->name = "adiabatic";
54  }
55 
57  = default;
58 
59  void
60  Adiabatic::declare_entries(Parameters &prm, const std::string & /*unused*/)
61  {
62  // Document plugin and require entries if needed.
63  prm.declare_entry("", Types::Object(),
64  "Adiabatic temperature model. Uses global values by default.");
65 
66  // Declare entries of this plugin
68  "The depth in meters from which the temperature of this feature is present.");
69 
70  prm.declare_entry("max depth", Types::OneOf(Types::Double(std::numeric_limits<double>::max()),Types::Array(Types::ValueAtPoints(std::numeric_limits<double>::max(), 2.))),
71  "The depth in meters to which the temperature of this feature is present.");
72 
73  prm.declare_entry("potential mantle temperature", Types::Double(-1),
74  "The potential temperature of the mantle at the surface in Kelvin. "
75  "If the value is lower then zero, the global value is used.");
76 
77  prm.declare_entry("thermal expansion coefficient", Types::Double(-1),
78  "The thermal expansion coefficient in $K^{-1}$. "
79  "If the value is lower then zero, the global value is used.");
80 
81  prm.declare_entry("specific heat", Types::Double(-1),
82  "The specific heat in $J kg^{-1} K^{-1}$. "
83  "If the value is lower then zero, the global value is used.");
84 
85  }
86 
87  void
88  Adiabatic::parse_entries(Parameters &prm, const std::vector<Point<2>> &coordinates)
89  {
90  min_depth_surface = Objects::Surface(prm.get("min depth",coordinates));
92  max_depth_surface = Objects::Surface(prm.get("max depth",coordinates));
94  operation = string_operations_to_enum(prm.get<std::string>("operation"));
95 
96  potential_mantle_temperature = prm.get<double>("potential mantle temperature");
99 
100 
101  thermal_expansion_coefficient = prm.get<double>("thermal expansion coefficient");
104 
105  specific_heat = prm.get<double>("specific heat");
106  if (specific_heat < 0)
108 
109  // Some assertions in debug mode can't hurt and have helped before.
111  "potential_mantle_temperature is not a number: " << potential_mantle_temperature << '.');
112  WBAssert(std::isfinite(potential_mantle_temperature),
113  "potential_mantle_temperature is not a finite: " << potential_mantle_temperature << '.');
114 
116  "thermal_expansion_coefficient is not a number: " << thermal_expansion_coefficient << '.');
118  "thermal_expansion_coefficient is not a finite: " << thermal_expansion_coefficient << '.');
119 
120  WBAssert(!std::isnan(specific_heat),
121  "specific_heat is not a number: " << specific_heat << '.');
123  "specific_heat is not a finite: " << specific_heat << '.');
124 
125  }
126 
127 
128  double
129  Adiabatic::get_temperature(const Point<3> & /*position_in_cartesian_coordinates*/,
130  const Objects::NaturalCoordinate &position_in_natural_coordinates,
131  const double depth,
132  const double gravity_norm,
133  double temperature_,
134  const double /*feature_min_depth*/,
135  const double /*feature_max_depth*/) const
136  {
137 
138  if (depth <= max_depth && depth >= min_depth)
139  {
140  const double min_depth_local = min_depth_surface.constant_value ? min_depth : min_depth_surface.local_value(position_in_natural_coordinates.get_surface_point()).interpolated_value;
141  const double max_depth_local = max_depth_surface.constant_value ? max_depth : max_depth_surface.local_value(position_in_natural_coordinates.get_surface_point()).interpolated_value;
142  if (depth <= max_depth_local && depth >= min_depth_local)
143  {
144  const double adabatic_temperature = potential_mantle_temperature *
145  std::exp(((thermal_expansion_coefficient * gravity_norm) /
146  specific_heat) * depth);
147 
148 
149  WBAssert(!std::isnan(adabatic_temperature),
150  "adabatic_temperature is not a number: " << adabatic_temperature << ". "
151  <<"Parameters: potential_mantle_temperature = " << potential_mantle_temperature
152  <<", thermal_expansion_coefficient = " << thermal_expansion_coefficient
153  << ", gravity_norm = " << gravity_norm
154  << ", specific_heat = " << specific_heat
155  << ", depth = " << depth);
156 
157  WBAssert(std::isfinite(adabatic_temperature),
158  "adabatic_temperature is not a finite: " << adabatic_temperature << '.');
159 
160  return apply_operation(operation,temperature_,adabatic_temperature);
161  }
162  }
163 
164  return temperature_;
165  }
166 
168  } // namespace Temperature
169  } // namespace MantleLayerModels
170  } // namespace Features
171 } // namespace WorldBuilder
172 
static void declare_entries(Parameters &prm, const std::string &parent_name="")
Definition: adiabatic.cc:60
const double DSNAN
Definition: nan.h:41
double potential_mantle_temperature
Definition: world.h:268
void parse_entries(Parameters &prm, const std::vector< Point< 2 >> &coordinates) override final
Definition: adiabatic.cc:88
#define WB_REGISTER_FEATURE_MANTLE_LAYER_TEMPERATURE_MODEL(classname, name)
Definition: interface.h:151
Operations string_operations_to_enum(const std::string &operation)
double get_temperature(const Point< 3 > &position, const Objects::NaturalCoordinate &position_in_natural_coordinates, const double depth, const double gravity, double temperature, const double feature_min_depth, const double feature_max_depth) const override final
Definition: adiabatic.cc:129
#define WBAssert(condition, message)
Definition: assert.h:27
double specific_heat
Definition: world.h:288
SurfaceValueInfo local_value(const Point< 2 > &check_point) const
Definition: surface.cc:149
double thermal_expansion_coefficient
Definition: world.h:283
double apply_operation(const Operations operation, const double old_value, const double new_value)
void declare_entry(const std::string &name, const Types::Interface &type, const std::string &documentation)
Definition: parameters.cc:197
T get(const std::string &name)