Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create reactive fluid transport material model #5245

Conversation

naliboff
Copy link
Contributor

@naliboff naliboff commented Jul 10, 2023

A draft material model, which composites on top of existing material models for solid deformation to also simulate reactive fluid transport. This is based on the contribution from #5214 and discussions with @jdannberg, @danieldouglas92, and @ryanstoner1.

The material is a work in progress and the PR was created to facilitate discussion. At present, the only option is to simulate non-reactive (insoluble) fluid flow, but the idea is to maintain a flexible structure and allow users to use add additional petrologic models of varying complexity.

For new features/models or changes of existing features:

  • I have tested my new feature locally to ensure it is correct.
  • I have created a testcase for the new feature/benchmark in the tests/ directory.
  • I have added a changelog entry in the doc/modules/changes directory that will inform other users of my change.

Copy link
Contributor

@jdannberg jdannberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I have looked through your PR and had some smaller comments, and I also think it would be good if you could reorder the functions. Usually, all material models have the same order of the functions (for example, the last 4 are always evaluate(), declare_parameters(), parse_parameters(), and create_additional_named_outputs()). Have a look at the other melt material models for the right order.

Maybe it would also be good if someone else could have a look (just to comment on if the general idea of this makes sense since it duplicates some code).

include/aspect/material_model/reactive_fluid_transport.h Outdated Show resolved Hide resolved
source/material_model/reactive_fluid_transport.cc Outdated Show resolved Hide resolved
source/material_model/reactive_fluid_transport.cc Outdated Show resolved Hide resolved
Comment on lines 273 to 275
// the melt (fluid) fraction at any point is thus equal to the
// porosity, which is determined by the assigned initial porosity,
// fluid boundary conditions, and fluid transport through the model.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure that this is true. If there is bound water, the total fluid fraction would not equal the porosity.
The free fluid fraction is equal to the porosity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I've modified the documentation and code accordingly.

source/material_model/reactive_fluid_transport.cc Outdated Show resolved Hide resolved
@@ -0,0 +1,155 @@
# This is a 1D test case for an insoluble fluid moving upwards in a
# narrow channel through porous coupled two-phase flow.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tester says: "test reactive_fluid_transport.prm is missing a folder with reference data"

tests/reactive_fluid_transport.prm Outdated Show resolved Hide resolved
Comment on lines 1 to 2
# This is a 1D test case for an insoluble fluid moving upwards in a
# narrow channel through porous coupled two-phase flow.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be more correct

Suggested change
# This is a 1D test case for an insoluble fluid moving upwards in a
# narrow channel through porous coupled two-phase flow.
# This is a 1D test case for a fluid moving upwards in a narrow channel
#through porous coupled two-phase flow without reacting with the solid rock.

Comment on lines 93 to 94
# We use a custom material model that implements the layers with
# different solubility.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is outdated

set Reference fluid viscosity = 10
set Reference permeability = 2.5e-6
set Exponential fluid weakening factor = 0
set Fluid reaction time scale for operator splitting = 5e4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But operator splitting is not used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, removed

@naliboff naliboff force-pushed the create_reactive_fluid_transport_material_model branch from 3d5b8ae to 1fdafa8 Compare July 10, 2023 15:49
@naliboff
Copy link
Contributor Author

@jdannberg - Thanks for the initial comments and suggestions, which I've addressed aside from the reordering the functions. I'll do the reordering next, finish the test case, and then add in a structure for specifying what reaction model to use. After that, a look from a second reviewer would be ideal.

@naliboff
Copy link
Contributor Author

@jdannberg @ryanstoner1 @danieldouglas92 - The functions have been re-ordered, a switch case is available for implementing different reaction schemes (current option is no reaction) and the test results have been added. It is probably ready for another round of reviews?

@bobmyhill - Would you be willing to take a look?

@naliboff
Copy link
Contributor Author

/rebuild

@naliboff
Copy link
Contributor Author

Topics for discussion when reviewing:

  1. What features should be present before this PR is merged (level of complexity)
  2. Will the current structure facilitate future expansion?
  3. Should the test case be modified to be based on a benchmark for simple Darcy flow?

Copy link
Contributor

@ryanstoner1 ryanstoner1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naliboff Some comments about settling on the semantics. Take them of leave them. Perhaps we can discuss some when we talk. Also, it might be good to go over how to best make this extensible if new users have their own reaction formulation.

case no_reaction:
{
// A fluid-rock reaction model where no reactions occur.
// The melt (fluid) fraction at any point is equal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps specify this to make a bit more transparent?

Suggested change
// The melt (fluid) fraction at any point is equal
// The melt (fluid) fraction (volume percent) at any point is equal

Comment on lines 115 to 116
// Modify the viscosity from the base model based on the presence of fluid.
const unsigned int porosity_idx = this->introspection().compositional_index_for_name("porosity");

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Modify the viscosity from the base model based on the presence of fluid.
const unsigned int porosity_idx = this->introspection().compositional_index_for_name("porosity");
const unsigned int porosity_idx = this->introspection().compositional_index_for_name("porosity");
// Modify the viscosity from the base model based on the presence of fluid.

Comment on lines 146 to 150
const double phi_0 = 0.05;
porosity = std::max(porosity,1e-8);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment could be nice here.

{
prm.declare_entry("Base model","visco plastic",
Patterns::Selection(MaterialModel::get_valid_model_names_pattern<dim>()),
"The name of a material model that will be modified by the "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"The name of a material model that will be modified by the "
"The name of a material model incorporating the "

Clarity.

Copy link
Member

@gassmoeller gassmoeller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I talked to @jdannberg and the general approach makes sense. Go ahead and address the comments.

@naliboff naliboff changed the title [WIP] Create reactive fluid transport material model Create reactive fluid transport material model Jul 14, 2023
@naliboff naliboff force-pushed the create_reactive_fluid_transport_material_model branch from 0147f46 to 4a69158 Compare July 14, 2023 18:10
@naliboff naliboff force-pushed the create_reactive_fluid_transport_material_model branch from 4a69158 to 5e5bd1c Compare July 14, 2023 20:10
Copy link
Contributor

@jdannberg jdannberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! The structure looks good now, but I think the implementation requires some changes. Most importantly, think about if you actually want no reactions, a zero solubility, or both.

@@ -0,0 +1,8 @@
New: There is now a new material ('reactive fluid
transport') that is designed to advect fluids and
compute luid release and absorption based on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
compute luid release and absorption based on
compute fluid release and absorption based on

@@ -0,0 +1,8 @@
New: There is now a new material ('reactive fluid
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
New: There is now a new material ('reactive fluid
New: There is now a new material model ('reactive fluid

transport') that is designed to advect fluids and
compute luid release and absorption based on
different models for fluid-rock interaction. The
that properties of the solid are taken from a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
that properties of the solid are taken from a
properties of the solid are taken from a

double fluid_reaction_time_scale;

/**
* Enumeration for selecting which type of scheme to use for reactions between.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Enumeration for selecting which type of scheme to use for reactions between.
* Enumeration for selecting which type of scheme to use for reactions between

{
// A fluid-rock reaction model where no reactions occur.
// The melt (fluid) fraction (volume percent) at any point is
// equal to the sume of the bound fluid content and porosity,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// equal to the sume of the bound fluid content and porosity,
// equal to the sum of the bound fluid content and porosity,

*/
enum ReactionScheme
{
no_reaction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

"computed. If the model does not use operator splitting, this parameter is not used. "
"Units: yr or s, depending on the ``Use years "
"in output instead of seconds'' parameter.");
prm.declare_entry ("Fluid solid reaction scheme", "no reaction",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would prefer this with a dash

Suggested change
prm.declare_entry ("Fluid solid reaction scheme", "no reaction",
prm.declare_entry ("Fluid-solid reaction scheme", "no reaction",



Postprocessing:
Compositions min/max/mass: -5.788e-07/0.11/5159 // 0/0/0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this is working as intended? Shouldn't the fluid be released, i.e. the porosity should increase?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, good catch! The initial assignment of values (porosity, bound_fluid) was reversed.

Comment on lines +167 to +181
for (unsigned int q=0; q<out.n_evaluation_points(); ++q)
for (unsigned int c=0; c<in.composition[q].size(); ++c)
{
double porosity_change = eq_free_fluid_fractions[q] - in.composition[q][porosity_idx];
// do not allow negative porosity
if (in.composition[q][porosity_idx] + porosity_change < 0)
porosity_change = -in.composition[q][porosity_idx];

if (c == bound_fluid_idx && this->get_timestep_number() > 0)
reaction_rate_out->reaction_rates[q][c] = - porosity_change / fluid_reaction_time_scale;
else if (c == porosity_idx && this->get_timestep_number() > 0)
reaction_rate_out->reaction_rates[q][c] = porosity_change / fluid_reaction_time_scale;
else
reaction_rate_out->reaction_rates[q][c] = 0.0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only works if you use operator splitting in your model. So (1), please document that, and (2) change your test to actually use operator splitting (because at the moment, it does not test this implementation because it does not use the reaction rates).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on what part of the code needs additional documentation for the operator splitting? There is some documentation at the top on this above the following if statement (if (this->get_parameters().use_operator_splitting && reaction_rate_out != nullptr)), but happy to more in an additional location.

The test has been updated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just having the assert is fine!

set End time = 1e1


set Use operator splitting = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to use operator splitting for your reactions to work.

@naliboff naliboff force-pushed the create_reactive_fluid_transport_material_model branch from bc91b01 to 2d54a9f Compare October 6, 2023 23:23
@naliboff naliboff force-pushed the create_reactive_fluid_transport_material_model branch from 2d54a9f to ce8be6f Compare October 6, 2023 23:40
@naliboff naliboff force-pushed the create_reactive_fluid_transport_material_model branch from 60310f6 to 71a5a05 Compare October 6, 2023 23:58
@naliboff
Copy link
Contributor Author

naliboff commented Oct 7, 2023

@jdannberg - Thanks for the thorough review! I've hopefully addressed most of the comments, and I think this is ready for another review.

Copy link
Contributor

@jdannberg jdannberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only have a few minor comments, otherwise this looks good!

* model is thus assuming that the bound water fraction is a
* volume fraction (i.e., since porosity is always a volume
* fraction). This latter assumption also requires the selected
* base model is incompressible, as otherwise the advection
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* base model is incompressible, as otherwise the advection
* base model to be incompressible, as otherwise the advection

# there is no need to use operator splitting.
set Use operator splitting = false

# Mellt transport is turned on to ensure it works
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Mellt transport is turned on to ensure it works
# Melt transport is turned on to ensure it works

set Reference fluid viscosity = 10
set Reference permeability = 2.5e-6
set Exponential fluid weakening factor = 0
set Fluid-solid reaction scheme = zero solubility
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be no reaction?
You switch the operator splitting off, so technically, this should give you the correct result, but I find it to be confusing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see it actually does not work because
Exception 'ExcMessage("The Fluid-reaction scheme zero solubility must be used with operator splitting.")'
:-)

@@ -0,0 +1,161 @@

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this empty line?

Comment on lines +1 to +7
# This model tests the reactive fluid transport material
# 'no reaction' scenario to ensure that there is no reaction
# between the fluid and solid phases. The values of
# porosity (0) and the bound fluid (0.01) are initially
# spatially uniform. The absence of reactions between
# the two phases and near zero velocities (free-slip on
# all sides) produces no change in their values through time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very similar to the zero solubility test below. Can you include the other test here with
include $ASPECT_SOURCE_DIR/tests/reactive_fluid_transport_zero_solubility.prm
and the only list the parameters that are different? This way you do not have to duplicate everything.

Comment on lines +34 to +35
Compositions min/max/mass: 0.01/0.01/4e+04 // 0/0/0
Melt fraction min/total/max: 0.01, 4e+04, 0.01
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shows nicely that it worked!

Comment on lines +167 to +181
for (unsigned int q=0; q<out.n_evaluation_points(); ++q)
for (unsigned int c=0; c<in.composition[q].size(); ++c)
{
double porosity_change = eq_free_fluid_fractions[q] - in.composition[q][porosity_idx];
// do not allow negative porosity
if (in.composition[q][porosity_idx] + porosity_change < 0)
porosity_change = -in.composition[q][porosity_idx];

if (c == bound_fluid_idx && this->get_timestep_number() > 0)
reaction_rate_out->reaction_rates[q][c] = - porosity_change / fluid_reaction_time_scale;
else if (c == porosity_idx && this->get_timestep_number() > 0)
reaction_rate_out->reaction_rates[q][c] = porosity_change / fluid_reaction_time_scale;
else
reaction_rate_out->reaction_rates[q][c] = 0.0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just having the assert is fine!

{
AssertThrow(fluid_reaction_time_scale >= this->get_parameters().reaction_time_step,
ExcMessage("The reaction time step " + Utilities::to_string(this->get_parameters().reaction_time_step)
+ " in the operator splitting scheme is too large to compute melting rates! "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
+ " in the operator splitting scheme is too large to compute melting rates! "
+ " in the operator splitting scheme is too large to compute fluid release rates! "

AssertThrow(fluid_reaction_time_scale >= this->get_parameters().reaction_time_step,
ExcMessage("The reaction time step " + Utilities::to_string(this->get_parameters().reaction_time_step)
+ " in the operator splitting scheme is too large to compute melting rates! "
"You have to choose it in such a way that it is smaller than the 'Melting time scale for "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"You have to choose it in such a way that it is smaller than the 'Melting time scale for "
"You have to choose it in such a way that it is smaller than the 'Fluid reaction time scale for "

Comment on lines 312 to 313
AssertThrow(this->get_material_model().is_compressible() == false,
ExcMessage("The Fluid-reaction scheme zero solubility must be used with an incompressible base model."));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not work well for all models, since at this point we have not parsed the parameters from the base model. So if the base model has a compressibility that depends on an input parameter, at this point in the code we will not know about it. It would be better to move this after parsing the parameters from the base model or ito the initialize() function.

@naliboff
Copy link
Contributor Author

naliboff commented Oct 7, 2023

@jdannberg - Thanks for the last round of edits! I addressed all of the comments, but there is still a bug I am tracking down so not ready to merge yet.

@naliboff
Copy link
Contributor Author

naliboff commented Dec 8, 2023

@jdannberg - I think this is ready to merged!

@jdannberg
Copy link
Contributor

This looks good to me now! The only other comment I have is that this also does not create the additional material model outputs the base model has (which I fixed for the prescribed viscosity and depth dependent model here #5547).

But that could be addressed in a follow-up PR.

And sorry this took me so long to look at!

@jdannberg jdannberg merged commit 3f38e93 into geodynamics:main Jan 31, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants