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