https://mooseframework.inl.gov
Loading...
Searching...
No Matches
AddCoupledEqSpeciesAction.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
11#include "Parser.h"
12#include "FEProblem.h"
13#include "Factory.h"
14#include "MooseError.h"
15
16#include "libmesh/string_to_enum.h"
17
18// Regular expression includes
19#include "pcrecpp.h"
20
21registerMooseAction("ChemicalReactionsApp", AddCoupledEqSpeciesAction, "add_kernel");
22
23registerMooseAction("ChemicalReactionsApp", AddCoupledEqSpeciesAction, "add_aux_kernel");
24
27{
29 params.addRequiredParam<std::vector<NonlinearVariableName>>(
30 "primary_species", "The list of primary variables to add");
31 params.addParam<std::vector<AuxVariableName>>(
32 "secondary_species", "The list of aqueous equilibrium species to be output as aux variables");
33 params.addParam<std::string>("reactions", "The list of aqueous equilibrium reactions");
34 params.addParam<std::vector<VariableName>>("pressure", {}, "Pressure variable");
35 RealVectorValue g(0, 0, 0);
36 params.addParam<RealVectorValue>("gravity", g, "Gravity vector (default is (0, 0, 0))");
37 params.addClassDescription("Adds coupled equilibrium Kernels and AuxKernels for primary species");
38 return params;
39}
40
42 : Action(params),
43 _primary_species(getParam<std::vector<NonlinearVariableName>>("primary_species")),
44 _secondary_species(getParam<std::vector<AuxVariableName>>("secondary_species")),
45 _weights(_primary_species.size()),
46 _primary_participation(_primary_species.size()),
47 _sto_u(_primary_species.size()),
48 _sto_v(_primary_species.size()),
49 _coupled_v(_primary_species.size()),
50 _input_reactions(getParam<std::string>("reactions")),
51 _pressure_var(getParam<std::vector<VariableName>>("pressure")),
52 _gravity(getParam<RealVectorValue>("gravity"))
53{
54 // Parse the aqueous equilibrium reactions
55 pcrecpp::RE re_reaction(
56 "(.+?)" // single reaction (any character until the equilibrium coefficient appears)
57 "\\s" // word boundary
58 "(" // start capture
59 "-?" // optional minus sign
60 "\\d+(?:\\.\\d*)?" // digits followed by optional decimal and more digits
61 ")" // end capture
62 "\\b" // word boundary
63 "(?:,?\\s*|$)" // optional comma or end of string
64 ,
65 pcrecpp::RE_Options().set_extended(true));
66
67 pcrecpp::RE re_terms("(\\S+)");
68 pcrecpp::RE re_coeff_and_species("(?: \\(? (.*?) \\)? )" // match the leading coefficent
69 "([A-Za-z].*)" // match the species
70 ,
71 pcrecpp::RE_Options().set_extended(true));
72
73 pcrecpp::StringPiece input(_input_reactions);
74
75 pcrecpp::StringPiece single_reaction, term;
76 std::string single_reaction_str;
77 Real eq_coeff;
78
79 // Parse reaction network to extract each individual reaction
80 while (re_reaction.FindAndConsume(&input, &single_reaction_str, &eq_coeff))
81 {
82 _reactions.push_back(single_reaction_str);
83 _eq_const.push_back(eq_coeff);
84 }
85
87
88 if (_num_reactions == 0)
89 mooseError("No equilibrium reaction provided!");
90
91 if (_pars.isParamValid("secondary_species"))
92 for (unsigned int k = 0; k < _secondary_species.size(); ++k)
94
95 // Start parsing each reaction
96 for (unsigned int i = 0; i < _num_reactions; ++i)
97 {
98 single_reaction = _reactions[i];
99
100 // Capture all of the terms
101 std::string species, coeff_str;
102 Real coeff;
103 int sign = 1;
104 bool secondary = false;
105
106 std::vector<Real> local_stos;
107 std::vector<VariableName> local_species_list;
108
109 // Find every single term in this reaction (species and operators)
110 while (re_terms.FindAndConsume(&single_reaction, &term))
111 {
112 // Separating the stoichiometric coefficients from species
113 if (re_coeff_and_species.PartialMatch(term, &coeff_str, &species))
114 {
115 if (coeff_str.length())
116 coeff = std::stod(coeff_str);
117 else
118 coeff = 1.0;
119
120 coeff *= sign;
121
122 if (secondary)
123 _eq_species.push_back(species);
124 else
125 {
126 local_stos.push_back(coeff);
127 local_species_list.push_back(species);
128 }
129 }
130 // Finding the operators and assign value of -1.0 to "-" sign
131 else if (term == "+" || term == "=" || term == "-")
132 {
133 if (term == "-")
134 {
135 sign = -1;
136 term = "+";
137 }
138 else
139 sign = 1;
140
141 if (term == "=")
142 secondary = true;
143 }
144 else
145 mooseError("Error parsing term: ", term.as_string());
146 }
147
148 _stos.push_back(local_stos);
149 _primary_species_involved.push_back(local_species_list);
150 }
151
152 // Start picking out primary species and coupled primary species and assigning
153 // corresponding stoichiomentric coefficients
154 for (unsigned int i = 0; i < _primary_species.size(); ++i)
155 {
156 _sto_u[i].resize(_num_reactions, 0.0);
157 _sto_v[i].resize(_num_reactions);
158 _coupled_v[i].resize(_num_reactions);
159 _weights[i].resize(_num_reactions, 0.0);
160
161 _primary_participation[i].resize(_num_reactions, false);
162 for (unsigned int j = 0; j < _num_reactions; ++j)
163 {
164 for (unsigned int k = 0; k < _primary_species_involved[j].size(); ++k)
166 _primary_participation[i][j] = true;
167
168 if (_primary_participation[i][j])
169 {
170 for (unsigned int k = 0; k < _primary_species_involved[j].size(); ++k)
171 {
173 {
174 _sto_u[i][j] = _stos[j][k];
175 _weights[i][j] = _stos[j][k];
176 }
177 else
178 {
179 _sto_v[i][j].push_back(_stos[j][k]);
180 _coupled_v[i][j].push_back(_primary_species_involved[j][k]);
181 }
182 }
183 }
184 }
185 }
186
187 // Print out details of the equilibrium reactions to the console
188 _console << "Aqueous equilibrium reactions:\n";
189 for (unsigned int i = 0; i < _num_reactions; ++i)
190 _console << " Reaction " << i + 1 << ": " << _reactions[i] << ", log10(Keq) = " << _eq_const[i]
191 << "\n";
192 _console << std::endl;
193}
194
195void
197{
198 if (_current_task == "add_kernel")
199 {
200 // Add Kernels for each primary species
201 for (unsigned int i = 0; i < _primary_species.size(); ++i)
202 {
203 for (unsigned int j = 0; j < _num_reactions; ++j)
204 {
205 if (_primary_participation[i][j])
206 {
207 InputParameters params_sub = _factory.getValidParams("CoupledBEEquilibriumSub");
208 params_sub.set<NonlinearVariableName>("variable") = _primary_species[i];
209 params_sub.set<Real>("weight") = _weights[i][j];
210 params_sub.defaultCoupledValue("log_k", _eq_const[j]);
211 params_sub.set<Real>("sto_u") = _sto_u[i][j];
212 params_sub.set<std::vector<Real>>("sto_v") = _sto_v[i][j];
213 params_sub.set<std::vector<VariableName>>("v") = _coupled_v[i][j];
214 _problem->addKernel("CoupledBEEquilibriumSub",
215 _primary_species[i] + "_" + _eq_species[j] + "_sub",
216 params_sub);
217
218 InputParameters params_cd = _factory.getValidParams("CoupledDiffusionReactionSub");
219 params_cd.set<NonlinearVariableName>("variable") = _primary_species[i];
220 params_cd.set<Real>("weight") = _weights[i][j];
221 params_cd.defaultCoupledValue("log_k", _eq_const[j]);
222 params_cd.set<Real>("sto_u") = _sto_u[i][j];
223 params_cd.set<std::vector<Real>>("sto_v") = _sto_v[i][j];
224 params_cd.set<std::vector<VariableName>>("v") = _coupled_v[i][j];
225 _problem->addKernel("CoupledDiffusionReactionSub",
226 _primary_species[i] + "_" + _eq_species[j] + "_cd",
227 params_cd);
228
229 // If pressure is coupled, add a CoupledConvectionReactionSub Kernel as well
230 if (_pars.isParamValid("pressure"))
231 {
232 InputParameters params_conv = _factory.getValidParams("CoupledConvectionReactionSub");
233 params_conv.set<NonlinearVariableName>("variable") = _primary_species[i];
234 params_conv.set<Real>("weight") = _weights[i][j];
235 params_conv.defaultCoupledValue("log_k", _eq_const[j]);
236 params_conv.set<Real>("sto_u") = _sto_u[i][j];
237 params_conv.set<std::vector<Real>>("sto_v") = _sto_v[i][j];
238 params_conv.set<std::vector<VariableName>>("v") = _coupled_v[i][j];
239 params_conv.set<std::vector<VariableName>>("p") = _pressure_var;
240 params_conv.set<RealVectorValue>("gravity") = _gravity;
241 _problem->addKernel("CoupledConvectionReactionSub",
242 _primary_species[i] + "_" + _eq_species[j] + "_conv",
243 params_conv);
244 }
245 }
246 }
247 }
248 }
249
250 if (_current_task == "add_aux_kernel")
251 {
252 // Add AqueousEquilibriumRxnAux AuxKernels for equilibrium species
253 for (unsigned int j = 0; j < _num_reactions; ++j)
254 {
255 if (_aux_species.find(_eq_species[j]) != _aux_species.end())
256 {
257 InputParameters params_eq = _factory.getValidParams("AqueousEquilibriumRxnAux");
258 params_eq.set<AuxVariableName>("variable") = _eq_species[j];
259 params_eq.defaultCoupledValue("log_k", _eq_const[j]);
260 params_eq.set<std::vector<Real>>("sto_v") = _stos[j];
261 params_eq.set<std::vector<VariableName>>("v") = _primary_species_involved[j];
262 _problem->addAuxKernel("AqueousEquilibriumRxnAux", "aux_" + _eq_species[j], params_eq);
263 }
264 }
265 }
266}
registerMooseAction("ChemicalReactionsApp", AddCoupledEqSpeciesAction, "add_kernel")
static InputParameters validParams()
std::shared_ptr< FEProblemBase > & _problem
const std::string & _current_task
const std::vector< AuxVariableName > _secondary_species
Secondary species added as AuxVariables.
std::vector< std::vector< std::vector< Real > > > _sto_v
Stoichiometric coefficients of coupled primary variables in each reaction.
const RealVectorValue _gravity
Gravity (default is (0, 0, 0))
std::vector< std::vector< bool > > _primary_participation
Participation of primary species in each reaction.
const std::vector< NonlinearVariableName > _primary_species
Basis set of primary species.
std::vector< std::string > _reactions
Vector of parsed reactions.
std::vector< Real > _eq_const
Equilibrium constants for each reaction.
std::vector< std::vector< Real > > _sto_u
Stoichiometric coefficients of primary variables in each reaction.
const std::vector< VariableName > _pressure_var
Pressure variable.
std::vector< std::vector< Real > > _weights
Weight of each primary species in each reaction.
std::vector< std::vector< std::vector< VariableName > > > _coupled_v
Coupled primary species for each reaction.
unsigned int _num_reactions
Number of reactions.
std::vector< std::vector< VariableName > > _primary_species_involved
Primary species involved in the ith equilibrium reaction.
AddCoupledEqSpeciesAction(const InputParameters &params)
std::vector< VariableName > _eq_species
Equilibrium species.
static InputParameters validParams()
std::vector< std::vector< Real > > _stos
Stoichiometric coefficients for each primary species in each reaction.
std::string _input_reactions
Reaction network read from input file.
std::set< std::string > _aux_species
Set of auxillary species.
const ConsoleStream _console
InputParameters getValidParams(const std::string &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
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
bool isParamValid(const std::string &name) const
void mooseError(Args &&... args) const
const InputParameters & _pars
Factory & _factory