Skip to content

Commit 986c9a9

Browse files
Track free water from each lithology
1 parent 1f11760 commit 986c9a9

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

include/aspect/material_model/reaction_model/tian2019_solubility.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ namespace aspect
9292
void
9393
parse_parameters (ParameterHandler &prm);
9494

95+
/**
96+
* A boolean that indicates whether the model tracks the contribution of each
97+
* lithology to the total volume fraction of free water.
98+
*/
99+
bool track_unique_water_components;
100+
95101
private:
96102

97103
/**

source/material_model/reaction_model/tian2019_solubility.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ namespace aspect
147147
void
148148
Tian2019Solubility<dim>::declare_parameters (ParameterHandler &prm)
149149
{
150+
prm.declare_entry ("Track source of free water", "false",
151+
Patterns::Bool(),
152+
"Whether to track the volume fraction of the free water that comes from each of the "
153+
"four rock compositions (sediment, MORB, gabbro, peridotite). If false, only the "
154+
"total water is tracked. If true, the total water, and the volume fraction from "
155+
"each rock composition is tracked. This requires defining four compositional fields: "
156+
"sediment_porosity, MORB_porosity, gabbro_porosity, and peridotite_porosity. ");
150157
prm.declare_entry ("Maximum weight percent water in sediment", "3",
151158
Patterns::Double (0),
152159
"The maximum allowed weight percent that the sediment composition can hold.");
@@ -178,6 +185,25 @@ namespace aspect
178185
AssertThrow(this->introspection().compositional_name_exists("peridotite"),
179186
ExcMessage("The Tian approximation only works "
180187
"if there is a compositional field called peridotite."));
188+
189+
track_unique_water_components = prm.get_bool ("Track source of free water");
190+
if (track_unique_water_components)
191+
{
192+
AssertThrow(this->introspection().compositional_name_exists("sediment_porosity"),
193+
ExcMessage("Tracking the contribution of free water sourced from sediment "
194+
"requires a compositional field named sediment_porosity."
195+
"if there is a compositional field called sediment."));
196+
AssertThrow(this->introspection().compositional_name_exists("MORB_porosity"),
197+
ExcMessage("Tracking the contribution of free water sourced from sediment "
198+
"requires a compositional field named MORB_porosity."));
199+
AssertThrow(this->introspection().compositional_name_exists("gabbro_porosity"),
200+
ExcMessage("Tracking the contribution of free water sourced from sediment "
201+
"requires a compositional field named gabbro_porosity."));
202+
AssertThrow(this->introspection().compositional_name_exists("peridotite_porosity"),
203+
ExcMessage("Tracking the contribution of free water sourced from sediment "
204+
"requires a compositional field named peridotite_porosity."));
205+
}
206+
181207
tian_max_peridotite_water = prm.get_double ("Maximum weight percent water in peridotite");
182208
tian_max_gabbro_water = prm.get_double ("Maximum weight percent water in gabbro");
183209
tian_max_MORB_water = prm.get_double ("Maximum weight percent water in MORB");

source/material_model/reactive_fluid_transport.cc

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ namespace aspect
188188

189189
if (fluid_solid_reaction_scheme != katz2003)
190190
{
191-
const unsigned int porosity_idx = this->introspection().compositional_index_for_name("porosity");
191+
const unsigned int porosity_idx = this->introspection().compositional_index_for_name("porosity");
192192

193193
// Modify the viscosity from the base model based on the presence of fluid.
194194
if (in.requests_property(MaterialProperties::viscosity))
@@ -252,6 +252,32 @@ namespace aspect
252252
std::vector<double> eq_free_fluid_fractions(out.n_evaluation_points());
253253
melt_fractions(in, eq_free_fluid_fractions, &out);
254254

255+
// Initialize the indices of compositional fields as invalid ints. These will
256+
// only be used if the Tian 2019 reaction model with tracking unique water components
257+
// is defined in the parameter file.
258+
unsigned int sediment_porosity_idx = numbers::invalid_unsigned_int;
259+
unsigned int MORB_porosity_idx = numbers::invalid_unsigned_int;
260+
unsigned int gabbro_porosity_idx = numbers::invalid_unsigned_int;
261+
unsigned int peridotite_porosity_idx = numbers::invalid_unsigned_int;
262+
263+
unsigned int sediment_idx = numbers::invalid_unsigned_int;
264+
unsigned int MORB_idx = numbers::invalid_unsigned_int;
265+
unsigned int gabbro_idx = numbers::invalid_unsigned_int;
266+
unsigned int peridotite_idx = numbers::invalid_unsigned_int;
267+
268+
if (tian2019_model.track_unique_water_components)
269+
{
270+
sediment_porosity_idx = this->introspection().compositional_index_for_name("sediment_porosity");
271+
MORB_porosity_idx = this->introspection().compositional_index_for_name("MORB_porosity");
272+
gabbro_porosity_idx = this->introspection().compositional_index_for_name("gabbro_porosity");
273+
peridotite_porosity_idx = this->introspection().compositional_index_for_name("peridotite_porosity");
274+
275+
sediment_idx = this->introspection().compositional_index_for_name("sediment");
276+
MORB_idx = this->introspection().compositional_index_for_name("MORB");
277+
gabbro_idx = this->introspection().compositional_index_for_name("gabbro");
278+
peridotite_idx = this->introspection().compositional_index_for_name("peridotite");
279+
}
280+
255281
for (unsigned int q=0; q<out.n_evaluation_points(); ++q)
256282
{
257283
const unsigned int bound_fluid_idx = this->introspection().compositional_index_for_name("bound_fluid");
@@ -274,7 +300,7 @@ namespace aspect
274300
// mass fraction of water in the solid, Fl_wt is the wt% of water in the fluid, and Fl_mass is
275301
// the mass fraction of water in the fluid. Fl_wt is always 100%, because the fluid is assumed to
276302
// be composed of only water. The bound_fluid composition gives Sm_wt, and we compute Sm_mass as
277-
// was done when defining mass_frac_porosity.
303+
// was done when defining mass_fraction_porosity.
278304
const double total_mass_fraction_water = in.composition[q][bound_fluid_idx] * (1 - volume_fraction_porosity) * solid_density / bulk_density +
279305
mass_fraction_porosity;
280306

@@ -286,7 +312,7 @@ namespace aspect
286312
// Since porosity is a volume fraction, convert the mass fraction change to a volume fraction change
287313
// to update the porosity value. We cannot use the bulk density to do this, because we do not yet know
288314
// the new bulk density of the rock after the reactions have been applied. We do this by substituting
289-
// the new bulk density as a function of the new volume fraction porosity into this equation:
315+
// the new bulk density as a function of the new volume fraction porosity into this equation:
290316
// new_Fl_mass * new_bulk_density = new_volume_frac * fluid_density
291317
// and solving for the new volume fraction. This gives us the following equation:
292318
const double new_volume_fraction_porosity = solid_density * new_mass_fraction_porosity /
@@ -324,6 +350,29 @@ namespace aspect
324350
reaction_rate_out->reaction_rates[q][c] = porosity_change / reaction_time_step_size;
325351
else
326352
reaction_rate_out->reaction_rates[q][c] = 0.0;
353+
354+
if (tian2019_model.track_unique_water_components)
355+
{
356+
// Determine what the fraction of each lithology is at the current quadrature point.
357+
const double sediment_percent = std::max(in.composition[q][sediment_idx], 0.0);
358+
const double MORB_percent = std::max(in.composition[q][MORB_idx], 0.0);
359+
const double gabbro_percent = std::max(in.composition[q][gabbro_idx], 0.0);
360+
const double peridotite_percent = std::max(in.composition[q][peridotite_idx], 0.0);
361+
362+
// The total porosity change is determined based on the average lithology at each point.
363+
// Therefore to track the porosity change for each lithology, we need to multiply the
364+
// total by the contribution of each lithology.
365+
const double porosity_change_for_tracking = porosity_change < 0 ? 0 : porosity_change;
366+
367+
if (c == sediment_porosity_idx)
368+
reaction_rate_out->reaction_rates[q][sediment_porosity_idx] = porosity_change_for_tracking / reaction_time_step_size * sediment_percent;
369+
else if (c == MORB_porosity_idx)
370+
reaction_rate_out->reaction_rates[q][MORB_porosity_idx] = porosity_change_for_tracking / reaction_time_step_size * MORB_percent;
371+
else if (c == gabbro_porosity_idx)
372+
reaction_rate_out->reaction_rates[q][gabbro_porosity_idx] = porosity_change_for_tracking / reaction_time_step_size * gabbro_percent;
373+
else if (c == peridotite_porosity_idx)
374+
reaction_rate_out->reaction_rates[q][peridotite_porosity_idx] = porosity_change_for_tracking / reaction_time_step_size * peridotite_percent;
375+
}
327376
}
328377
}
329378
}

0 commit comments

Comments
 (0)