World Builder  1.1.0-pre
A geodynamic initial conditions generator
plate_model_constant_age.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 "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  namespace OceanicPlateModels
39  {
40  namespace Temperature
41  {
42  PlateModelConstantAge::PlateModelConstantAge(WorldBuilder::World *world_)
43  :
44  min_depth(NaN::DSNAN),
45  max_depth(NaN::DSNAN),
46  top_temperature(NaN::DSNAN),
47  bottom_temperature(NaN::DSNAN),
48  operation(Operations::REPLACE)
49  {
50  this->world = world_;
51  this->name = "plate model constant age";
52  }
53 
55  = default;
56 
57  void
58  PlateModelConstantAge::declare_entries(Parameters &prm, const std::string & /*unused*/)
59  {
60  // Document plugin and require entries if needed.
61  // Add temperature to the required parameters.
62  prm.declare_entry("", Types::Object({"max depth"}),
63  "Plate model, but with a fixed age.");
64 
65  // Declare entries of this plugin
67  "The depth in meters from which the temperature of this feature is present.");
68 
69  prm.declare_entry("max depth", Types::OneOf(Types::Double(std::numeric_limits<double>::max()),Types::Array(Types::ValueAtPoints(std::numeric_limits<double>::max(), 2.))),
70  "The depth in meters to which the temperature of this feature is present.");
71 
72  prm.declare_entry("top temperature", Types::Double(293.15),
73  "The temperature in degree Kelvin which this feature should have");
74 
75  prm.declare_entry("bottom temperature", Types::Double(-1),
76  "The temperature in degree Kelvin which this feature should have");
77 
78  prm.declare_entry("plate age", Types::Double(80e3),
79  "The age of the plate in year. "
80  "This age is assigned to the whole plate. ");
81  }
82 
83  void
84  PlateModelConstantAge::parse_entries(Parameters &prm, const std::vector<Point<2>> &coordinates)
85  {
86 
87  min_depth_surface = Objects::Surface(prm.get("min depth",coordinates));
89  max_depth_surface = Objects::Surface(prm.get("max depth",coordinates));
91  operation = string_operations_to_enum(prm.get<std::string>("operation"));
92  top_temperature = prm.get<double>("top temperature");
93  bottom_temperature = prm.get<double>("bottom temperature");
94  plate_age = prm.get<double>("plate age")*31557600;
95  }
96 
97 
98  double
100  const Objects::NaturalCoordinate &position_in_natural_coordinates,
101  const double depth,
102  const double gravity_norm,
103  double temperature_,
104  const double /*feature_min_depth*/,
105  const double /*feature_max_depth*/) const
106  {
107  if (depth <= max_depth && depth >= min_depth)
108  {
109  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;
110  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;
111  if (depth <= max_depth_local && depth >= min_depth_local)
112  {
113  double bottom_temperature_local = bottom_temperature;
114 
115  if (bottom_temperature_local < 0)
116  {
117  bottom_temperature_local = this->world->potential_mantle_temperature *
118  std::exp(((this->world->thermal_expansion_coefficient* gravity_norm) /
119  this->world->specific_heat) * depth);
120  }
121  const int sommation_number = 100;
122 
123  // some aliases
124  //const double top_temperature = top_temperature;
125  const double thermal_diffusivity = this->world->thermal_diffusivity;
126  double temperature = top_temperature + (bottom_temperature_local - top_temperature) * (depth / max_depth);
127 
128  // This formula ignores the horizontal heat transfer by just having the age of the plate in it.
129  // (Chapter 7 Heat, Fowler M. The solid earth: an introduction to global geophysics[M]. Cambridge University Press, 1990)
130  for (int i = 1; i<sommation_number+1; ++i)
131  {
132  temperature = temperature + (bottom_temperature_local - top_temperature) *
133  ((2 / (double(i) * Consts::PI)) * std::sin((double(i) * Consts::PI * depth) / max_depth) *
134  std::exp(-1.0 * i * i * Consts::PI * Consts::PI * thermal_diffusivity * plate_age / (max_depth * max_depth)));
135  }
136 
137  WBAssert(!std::isnan(temperature), "Temperature inside plate model constant age is not a number: " << temperature
138  << ". Relevant variables: bottom_temperature_local = " << bottom_temperature_local
139  << ", top_temperature = " << top_temperature
140  << ", max_depth = " << max_depth
141  << ", thermal_diffusivity = " << thermal_diffusivity
142  << ", age = " << plate_age << '.');
143  WBAssert(std::isfinite(temperature), "Temperature inside plate model constant age is not a finite: " << temperature << ". Relevant variables: bottom_temperature_local = " << bottom_temperature_local
144  << ", top_temperature = " << top_temperature
145  << ", thermal_diffusivity = " << thermal_diffusivity
146  << ", age = " << plate_age << '.');
147 
148 
149  return apply_operation(operation,temperature_,temperature);
150 
151  }
152  }
153  return temperature_;
154  }
155 
157  } // namespace Temperature
158  } // namespace OceanicPlateModels
159  } // namespace Features
160 } // namespace WorldBuilder
161 
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
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
Operations string_operations_to_enum(const std::string &operation)
#define WBAssert(condition, message)
Definition: assert.h:27
#define WB_REGISTER_FEATURE_OCEANIC_PLATE_TEMPERATURE_MODEL(classname, name)
Definition: interface.h:151
double thermal_diffusivity
Definition: world.h:293
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)
double sin(const double raw_angle)
Definition: point.h:81
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
T get(const std::string &name)
static void declare_entries(Parameters &prm, const std::string &parent_name="")