37 using namespace Utilities;
41 namespace OceanicPlateModels
47 min_depth(NaN::
DSNAN),
48 max_depth(NaN::
DSNAN),
52 this->
name =
"water content";
64 "TianWaterContent compositional model. Sets bound water content as a compositional field. The returned " 65 "water content is based on the the temperature and pressure at a point within the world. Currently, " 66 "the bound water content can be determined for four different lithologies: 'sediment', mid-ocean " 67 "ridge basalt ('MORB'), 'gabbro', and 'peridotite', using parameterized phase diagrams from Tian et al., 2019 " 68 "(https://doi.org/10.1029/2019GC008488). The pressure is lithostatic, calculated with a constant user defined " 69 "density, and is limited by a user defined cutoff pressure (in GPa) for each lithology. This is required because the " 70 "parameterization breaks down at large pressures. Recommended cutoff pressures are 10 GPa is used for 'peridotite', " 71 "26 GPa is used for 'gabbro', 16 GPa is used for 'MORB', and 1 GPa is used for 'sediment'.");
75 "The depth in meters from which the composition of this feature is present.");
77 "The depth in meters to which the composition of this feature is present.");
79 "A list with the labels of the composition which are present there.");
81 "The reference density used for determining the lithostatic pressure for calculating " 82 "the bound water content.");
84 "The lithology used to determine which polynomials to use for calculating the water content. Valid options are: " 85 "'sediment', 'MORB', 'gabbro', and 'peridotite'.");
87 "The value of the initial water content (in wt%) for the lithology at the trench. This represents the " 88 "max value applied to this lithology.");
90 "The upper bound for the pressure, in GPa, for the specified lithology in the Tian parameterization. This is necessary because " 91 "the parameterization breaks down for high pressures. It is recommended that 10 GPa is used for 'peridotite', 26 GPa is used for " 92 "'gabbro', 16 GPa is used for 'MORB', and 1 GPa is used for 'sediment'.");
93 prm.
declare_entry(
"operation",
Types::String(
"replace", std::vector<std::string> {
"replace",
"replace defined only",
"add",
"subtract"}),
94 "Whether the value should replace any value previously defined at this location (replace) or " 95 "add the value to the previously define value. Replacing implies that all compositions not " 96 "explicitly defined are set to zero. To only replace the defined compositions use the replace only defined option.");
111 std::string lithology_string = prm.
get<std::string>(
"lithology");
113 if (lithology_string==
"peridotite")
115 else if (lithology_string==
"gabbro")
117 else if (lithology_string==
"MORB")
119 else if (lithology_string==
"sediment")
126 double temperature)
const 128 double ln_LR_value = 0;
129 double ln_c_sat_value = 0;
131 std::vector<double> LR_polynomial_coeffs;
132 std::vector<double> c_sat_polynomial_coeffs;
133 std::vector<double> Td_polynomial_coeffs;
148 for (
unsigned int LR_coeff_index = 0; LR_coeff_index <
LR_poly[
lithology_type].size(); ++LR_coeff_index)
152 for (
unsigned int Td_coeff_index = 0; Td_coeff_index <
Td_poly[
lithology_type].size(); ++Td_coeff_index)
155 double partition_coeff = std::exp(ln_c_sat_value) * std::exp(std::exp(ln_LR_value) * (1/temperature - 1/Td_value));
156 return partition_coeff;
164 const unsigned int composition_number,
169 if (depth <= max_depth && depth >=
min_depth)
173 if (depth <= max_depth_local && depth >= min_depth_local)
177 const double lithostatic_pressure = std::max(0.5, std::min(
density * 9.81 * depth / 1e9,
cutoff_pressure));
178 const double slab_temperature =
world->
properties(position_in_cartesian_coordinates.
get_array(), depth, {{{1,0,0}}})[0];
183 partition_coefficient = std::min(
max_water_content, partition_coefficient) / 100;
LithologyName lithology_type
double calculate_water_content(double pressure, double temperature) const
#define WB_REGISTER_FEATURE_OCEANIC_PLATE_COMPOSITION_MODEL(classname, name)
~TianWaterContent() override final
static void declare_entries(Parameters &prm, const std::string &parent_name="")
std::vector< double > properties(const std::array< double, 2 > &point, const double depth, const std::vector< std::array< unsigned int, 3 >> &properties) const
std::vector< std::vector< double > > c_sat_poly
const std::array< double, dim > & get_array() const
Operations string_operations_to_enum(const std::string &operation)
std::vector< unsigned int > compositions
Objects::Surface max_depth_surface
Point< 2 > get_surface_point() const
std::vector< std::vector< double > > Td_poly
void parse_entries(Parameters &prm, const std::vector< Point< 2 >> &coordinates) override final
Objects::Surface min_depth_surface
WorldBuilder::World * world
SurfaceValueInfo local_value(const Point< 2 > &check_point) const
double get_composition(const Point< 3 > &position, const Objects::NaturalCoordinate &position_in_natural_coordinates, const double depth, const unsigned int composition_number, double composition, const double feature_min_depth, const double feature_max_depth) const override final
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)
std::vector< T > get_vector(const std::string &name)
T get(const std::string &name)
std::vector< std::vector< double > > LR_poly