https://mooseframework.inl.gov
Loading...
Searching...
No Matches
AqueousReactionsEquilibriumPhysics.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
12
13// Register the actions for the objects actually used
14registerMooseAction("ChemicalReactionsApp", AqueousReactionsEquilibriumPhysics, "add_kernel");
15registerMooseAction("ChemicalReactionsApp", AqueousReactionsEquilibriumPhysics, "add_aux_kernel");
17
20{
22 params.addClassDescription("Forms the equations for the chemical reaction networks in a fluid"
23 " medium using a continuous Galerkin finite element discretization.");
24
25 // Rename parameters to match the previously existing actions for AqueousEquilibrium
26 // ReactionNetwork
27 params.renameParam("solver_variables", "primary_species", "The list of primary species to add");
28 params.renameParam(
29 "auxiliary_variables", "secondary_species", "The list of secondary species to add");
30 params.renameParam(
31 "variable_order", "order", "Order of both the primary and secondary species variables");
32 params.renameParam("equation_scaling", "scaling", "");
33 params.setDocString("reactions", "The list of equilibrium reactions occuring in the fluid");
34
35 // To preserve the legacy option to perform Darcy-advection with AqueousEquilibrium
36 // ReactionNetwork
37 params.addParam<bool>("add_darcy_advection_term",
38 false,
39 "Whether to add an advection term using the Darcy equation to compute the "
40 "advecting velocity");
41 params.addParam<std::vector<VariableName>>(
42 "pressure", {}, "Pressure variable (for Darcy advection)");
43 params.addParam<RealVectorValue>(
44 "gravity", RealVectorValue(0, 0, -9.81), "Gravity vector (for Darcy advection)");
45
46 return params;
47}
48
50 const InputParameters & parameters)
51 : ReactionNetworkPhysicsBase(parameters),
52 _sto_u(_num_solver_species),
53 _sto_v(_num_solver_species),
54 _weights(_num_solver_species),
55 _primary_participation(_num_solver_species),
56 _coupled_v(_num_solver_species),
57 _pressure_var(getParam<std::vector<VariableName>>("pressure"))
58{
59 // Further parse the reactions
60 // Keeping the data in these vectors of vectors as an intermediate processing step
61 for (const auto i : index_range(_reactions))
62 {
63 const auto & reaction = _reactions[i];
64 _solver_species_involved.push_back(reaction.getReactantSpecies());
65 _stos.push_back(reaction.getStoichiometricCoefficients());
66
67 // There are only one equilibrium species. We look at the output species
68 const auto & products = reaction.getProductSpecies();
69 if (products.size() != 1)
70 mooseError("Reaction:\n" + _reactions_input[i] +
71 "\n has more than one product species (on the RHS). This Physics only supports "
72 "one product species per reaction");
73 _eq_species.push_back(products[0]);
74
75 // If user passed log_K use that, else use K
76 if (reaction.hasMetaData<Real>("log10_K"))
77 _log_eq_const.push_back(std::stod(reaction.getMetaData("log10_K")));
78 else if (reaction.hasMetaData<Real>("K"))
79 _log_eq_const.push_back(std::log10(std::stod(reaction.getMetaData("K"))));
80 else if (reaction.hasMetaData("K") || reaction.hasMetaData("log10_K"))
81 paramError("reactions",
82 "Equilibrium constant species in square brackets must be specified as a float, "
83 "not a name");
84 else
85 paramError("reactions",
86 "Reaction: '" + _reactions_input[i] +
87 "'\n is missing an equilibrium constant [K=] or its logarithm [log10_K=] in "
88 "its metadata");
89 }
90
91 // For each primary/solver species, we examine the reactions to get the coefficients
92 // and various constants
93 for (unsigned int i = 0; i < _solver_species.size(); ++i)
94 {
95 _sto_u[i].resize(_num_reactions, 0.0);
96 _sto_v[i].resize(_num_reactions);
97 _coupled_v[i].resize(_num_reactions);
98 _weights[i].resize(_num_reactions, 0.0);
99
100 _primary_participation[i].resize(_num_reactions, false);
101 for (unsigned int j = 0; j < _num_reactions; ++j)
102 {
103 // Set the booleans for involvement in a reaction
104 for (unsigned int k = 0; k < _solver_species_involved[j].size(); ++k)
106 _primary_participation[i][j] = true;
107
108 if (_primary_participation[i][j])
109 {
110 for (unsigned int k = 0; k < _solver_species_involved[j].size(); ++k)
111 {
112 // Re-sort the coefficients into a more convenient format
114 {
115 _sto_u[i][j] = _stos[j][k];
116 _weights[i][j] = _stos[j][k];
117 }
118 else
119 {
120 _sto_v[i][j].push_back(_stos[j][k]);
121 _coupled_v[i][j].push_back(_solver_species_involved[j][k]);
122 }
123 }
124 }
125 }
126 }
127
128 // Parameter checks
129 checkSecondParamSetOnlyIfFirstOneTrue("add_darcy_advection_term", "pressure");
130 checkSecondParamSetOnlyIfFirstOneTrue("add_darcy_advection_term", "gravity");
131}
132
133void
135{
136 // Add Kernels for each primary species
137 // Note that the equations are on a per-species basis!
138 // So equations are organized differently than reactions
139 for (const auto i : index_range(_solver_species))
140 {
141 for (const auto j : make_range(_num_reactions))
142 {
143 if (_primary_participation[i][j])
144 {
145 {
146 InputParameters params_sub = _factory.getValidParams("CoupledBEEquilibriumSub");
147 assignBlocks(params_sub, _blocks);
148 params_sub.set<NonlinearVariableName>("variable") = _solver_species[i];
149 params_sub.set<Real>("weight") = _weights[i][j];
150 params_sub.defaultCoupledValue("log_k", _log_eq_const[j]);
151 params_sub.set<Real>("sto_u") = _sto_u[i][j];
152 params_sub.set<std::vector<Real>>("sto_v") = _sto_v[i][j];
153 params_sub.set<std::vector<VariableName>>("v") = _coupled_v[i][j];
154 _problem->addKernel("CoupledBEEquilibriumSub",
155 _solver_species[i] + "_" + _eq_species[j] + "_sub",
156 params_sub);
157 }
158
159 {
160 InputParameters params_cd = _factory.getValidParams("CoupledDiffusionReactionSub");
161 assignBlocks(params_cd, _blocks);
162 params_cd.set<NonlinearVariableName>("variable") = _solver_species[i];
163 params_cd.set<Real>("weight") = _weights[i][j];
164 params_cd.defaultCoupledValue("log_k", _log_eq_const[j]);
165 params_cd.set<Real>("sto_u") = _sto_u[i][j];
166 params_cd.set<std::vector<Real>>("sto_v") = _sto_v[i][j];
167 params_cd.set<std::vector<VariableName>>("v") = _coupled_v[i][j];
168 _problem->addKernel("CoupledDiffusionReactionSub",
169 _solver_species[i] + "_" + _eq_species[j] + "_cd",
170 params_cd);
171 }
172
173 // If pressure is coupled, add a CoupledConvectionReactionSub Kernel as well
174 if (getParam<bool>("add_darcy_advection_term") && isParamValid("pressure"))
175 {
176 InputParameters params_conv = _factory.getValidParams("CoupledConvectionReactionSub");
177 assignBlocks(params_conv, _blocks);
178 params_conv.set<NonlinearVariableName>("variable") = _solver_species[i];
179 params_conv.set<Real>("weight") = _weights[i][j];
180 params_conv.defaultCoupledValue("log_k", _log_eq_const[j]);
181 params_conv.set<Real>("sto_u") = _sto_u[i][j];
182 params_conv.set<std::vector<Real>>("sto_v") = _sto_v[i][j];
183 params_conv.set<std::vector<VariableName>>("v") = _coupled_v[i][j];
184 params_conv.set<std::vector<VariableName>>("p") = _pressure_var;
185 params_conv.set<RealVectorValue>("gravity") = getParam<RealVectorValue>("gravity");
186 _problem->addKernel("CoupledConvectionReactionSub",
187 _solver_species[i] + "_" + _eq_species[j] + "_conv",
188 params_conv);
189 }
190 }
191 }
192 }
193}
194
195void
197{
198 // Add AqueousEquilibriumRxnAux AuxKernels for equilibrium species
199 for (const auto j : make_range(_num_reactions))
200 {
201 // Add these aux-kernels only for the aux species involved in the reaction
202 // we should not be adding them twice, since only 1 eq_species per reaction
203 if (std::find(_aux_species.begin(), _aux_species.end(), _eq_species[j]) != _aux_species.end())
204 {
205 InputParameters params_eq = _factory.getValidParams("AqueousEquilibriumRxnAux");
206 assignBlocks(params_eq, _blocks);
207 params_eq.set<AuxVariableName>("variable") = _eq_species[j];
208 params_eq.defaultCoupledValue("log_k", _log_eq_const[j]);
209 mooseAssert(_stos[j].size() >= _solver_species_involved[j].size(),
210 "Coefs are for solver + auxiliary");
211 std::vector<Real> stos_primary(_stos[j].begin(),
212 _stos[j].begin() + _solver_species_involved[j].size());
213 params_eq.set<std::vector<Real>>("sto_v") = stos_primary;
214 params_eq.set<std::vector<VariableName>>("v") = _solver_species_involved[j];
215 getProblem().addAuxKernel("AqueousEquilibriumRxnAux", "aux_" + _eq_species[j], params_eq);
216 }
217 }
218}
registerMooseAction("ChemicalReactionsApp", AqueousReactionsEquilibriumPhysics, "add_kernel")
registerReactionNetworkPhysicsBaseTasks("ChemicalReactionsApp", AqueousReactionsEquilibriumPhysics)
std::shared_ptr< FEProblemBase > & _problem
Creates all the objects needed to solve a reaction network of chemical reactions at equilibrium in an...
const std::vector< VariableName > & _pressure_var
Name of the pressure variable.
std::vector< std::vector< bool > > _primary_participation
Vector of vectors, indexed by (i, j), of whether primary solver species 'i' is present in reaction 'j...
AqueousReactionsEquilibriumPhysics(const InputParameters &parameters)
std::vector< std::vector< Real > > _stos
Stoichiometric coefficients for each primary species (outer indexing) in each reaction.
std::vector< std::vector< Real > > _sto_u
Stoichiometric coefficients of primary/solver variables (outer indexing) in each reaction.
std::vector< std::vector< std::vector< VariableName > > > _coupled_v
Coupled primary species for each reaction (outer indexing is primary species, then reactions then inn...
std::vector< VariableName > _eq_species
Equilibrium species: only one per reaction. This is a restriction of this implementation.
std::vector< std::vector< VariableName > > _solver_species_involved
Primary species involved in the ith equilibrium reaction (outer indexing)
std::vector< std::vector< Real > > _weights
Weight of each primary species (outer indexing) in each reaction.
std::vector< Real > _log_eq_const
log10(Equilibrium constants) for each reaction
std::vector< std::vector< std::vector< Real > > > _sto_v
Stoichiometric coefficients of coupled primary variables (outer indexing) in each reaction.
virtual void addAuxKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
InputParameters getValidParams(const std::string &name) const
void checkSecondParamSetOnlyIfFirstOneTrue(const std::string &param1, const std::string &param2) const
void renameParam(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
void setDocString(const std::string &name, const std::string &doc)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
Real defaultCoupledValue(const std::string &coupling_name, unsigned int i=0) const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
Factory & _factory
virtual FEProblemBase & getProblem()
void assignBlocks(InputParameters &params, const std::vector< SubdomainName > &blocks) const
std::vector< SubdomainName > _blocks
Base class to host all common parameters and attributes of Physics actions to solve equations for mul...
const std::vector< ReactionNetworkUtils::Reaction > _reactions
Reaction network after being parsed in initializePhysics()
std::vector< std::string > _reactions_input
Reaction network as a vector of lines for pretty output.
static InputParameters validParams()
const std::vector< AuxVariableName > & _aux_species
Name of the species variables that can be computed without additional solves, simply auxkernels.
const unsigned int _num_reactions
Number of reactions involved in the network.
const std::vector< VariableName > & _solver_species
Name of the species variables to solve for in the reaction network.