https://mooseframework.inl.gov
AddCoupledSolidKinSpeciesAction.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 "MooseUtils.h"
12 #include "FEProblem.h"
13 #include "Factory.h"
14 #include "MooseError.h"
15 #include "Parser.h"
16 #include <algorithm>
17 
18 // Regular expression includes
19 #include "pcrecpp.h"
20 
21 registerMooseAction("ChemicalReactionsApp", AddCoupledSolidKinSpeciesAction, "add_kernel");
22 
23 registerMooseAction("ChemicalReactionsApp", AddCoupledSolidKinSpeciesAction, "add_aux_kernel");
24 
27 {
29  params.addRequiredParam<std::vector<NonlinearVariableName>>("primary_species",
30  "The list of primary species to add");
31  params.addParam<std::vector<AuxVariableName>>(
32  "secondary_species", "The list of solid kinetic species to be output as aux variables");
33  params.addRequiredParam<std::string>("kin_reactions", "The list of solid kinetic reactions");
34  params.addRequiredParam<std::vector<Real>>("log10_keq",
35  "The list of equilibrium constants for all reactions");
36  params.addRequiredParam<std::vector<Real>>(
37  "specific_reactive_surface_area",
38  "The list of specific reactive surface area for all minerals (m^2/L)");
39  params.addRequiredParam<std::vector<Real>>(
40  "kinetic_rate_constant", "The list of kinetic rate constant for all reactions (mol/m^2/s)");
41  params.addRequiredParam<std::vector<Real>>(
42  "activation_energy", "The list of activation energy values for all reactions (J/mol)");
43  params.addParam<Real>("gas_constant", 8.314, "Gas constant. Default is 8.314 (J/mol/K)");
44  params.addRequiredParam<std::vector<Real>>(
45  "reference_temperature", "The list of reference temperatures for all reactions (K)");
46  params.addRequiredCoupledVar("system_temperature",
47  "The system temperature for all reactions (K)");
48  params.addClassDescription("Adds solid kinetic Kernels and AuxKernels for primary species");
49  return params;
50 }
51 
53  : Action(params),
54  _primary_species(getParam<std::vector<NonlinearVariableName>>("primary_species")),
55  _secondary_species(getParam<std::vector<AuxVariableName>>("secondary_species")),
56  _kinetic_species_involved(_primary_species.size()),
57  _weights(_primary_species.size()),
58  _input_reactions(getParam<std::string>("kin_reactions")),
59  _logk(getParam<std::vector<Real>>("log10_keq")),
60  _r_area(getParam<std::vector<Real>>("specific_reactive_surface_area")),
61  _ref_kconst(getParam<std::vector<Real>>("kinetic_rate_constant")),
62  _e_act(getParam<std::vector<Real>>("activation_energy")),
63  _gas_const(getParam<Real>("gas_constant")),
64  _ref_temp(getParam<std::vector<Real>>("reference_temperature")),
65  _sys_temp(getParam<std::vector<VariableName>>("system_temperature"))
66 {
67  // Note: as the reaction syntax has changed, check to see if the old syntax has
68  // been used and throw an informative error. The number of = signs should be one
69  // more than the number of commas, while the smallest number of spaces possible is 2
70  bool old_syntax = false;
71  if (std::count(_input_reactions.begin(), _input_reactions.end(), '=') !=
72  std::count(_input_reactions.begin(), _input_reactions.end(), ',') + 1)
73  old_syntax = true;
74 
75  if (std::count(_input_reactions.begin(), _input_reactions.end(), ' ') < 2)
76  old_syntax = true;
77 
78  if (old_syntax)
79  mooseError("Old solid kinetic reaction syntax present.\nReactions should now be comma "
80  "separated, and must have spaces between species and +/-/= operators.\n"
81  "See #9972 for details");
82 
83  // Parse the kinetic reactions
84  pcrecpp::RE re_reactions("(.+?)" // A single reaction (any character until the comma delimiter)
85  "(?:,\\s*|$)" // comma or end of string
86  ,
87  pcrecpp::RE_Options().set_extended(true));
88 
89  pcrecpp::RE re_terms("(\\S+)");
90  pcrecpp::RE re_coeff_and_species("(?: \\(? (.*?) \\)? )" // match the leading coefficent
91  "([A-Za-z].*)" // match the species
92  ,
93  pcrecpp::RE_Options().set_extended(true));
94 
95  pcrecpp::StringPiece input(_input_reactions);
96  pcrecpp::StringPiece single_reaction, term;
97  std::string single_reaction_str;
98 
99  // Parse reaction network to extract each individual reaction
100  while (re_reactions.FindAndConsume(&input, &single_reaction_str))
101  _reactions.push_back(single_reaction_str);
102 
103  _num_reactions = _reactions.size();
104 
105  if (_num_reactions == 0)
106  mooseError("No solid kinetic reaction provided!");
107 
108  // Start parsing each reaction
109  for (unsigned int i = 0; i < _num_reactions; ++i)
110  {
111  single_reaction = _reactions[i];
112 
113  // Capture all of the terms
114  std::string species, coeff_str;
115  Real coeff;
116  int sign = 1;
117  bool secondary = false;
118 
119  std::vector<Real> local_stos;
120  std::vector<VariableName> local_species_list;
121 
122  // Find every single term in this reaction (species and operators)
123  while (re_terms.FindAndConsume(&single_reaction, &term))
124  {
125  // Separating the stoichiometric coefficients from species
126  if (re_coeff_and_species.PartialMatch(term, &coeff_str, &species))
127  {
128  if (coeff_str.length())
129  coeff = std::stod(coeff_str);
130  else
131  coeff = 1.0;
132 
133  coeff *= sign;
134 
135  if (secondary)
136  _solid_kinetic_species.push_back(species);
137  else
138  {
139  local_stos.push_back(coeff);
140  local_species_list.push_back(species);
141  }
142  }
143  // Finding the operators and assign value of -1.0 to "-" sign
144  else if (term == "+" || term == "=" || term == "-")
145  {
146  if (term == "-")
147  {
148  sign = -1;
149  term = "+";
150  }
151 
152  if (term == "=")
153  secondary = true;
154  }
155  else
156  mooseError("Error parsing term: ", term.as_string());
157  }
158 
159  _stos.push_back(local_stos);
160  _primary_species_involved.push_back(local_species_list);
161  }
162 
163  // Start picking out primary species and coupled primary species and assigning
164  // corresponding stoichiomentric coefficients
165  for (unsigned int i = 0; i < _primary_species.size(); ++i)
166  for (unsigned int j = 0; j < _num_reactions; ++j)
167  {
168  for (unsigned int k = 0; k < _primary_species_involved[j].size(); ++k)
170  {
171  _weights[i].push_back(_stos[j][k]);
173  }
174  }
175 
176  // Print out details of the solid kinetic reactions to the console
177  _console << "Solid kinetic reactions:\n";
178  for (unsigned int i = 0; i < _num_reactions; ++i)
179  _console << " Reaction " << i + 1 << ": " << _reactions[i] << "\n";
180  _console << std::endl;
181 
182  // Check that all secondary species read from the reaction network have been added
183  // as AuxVariables. Note: can't sort the _solid_kinetic_species vector as it throws
184  // out the species and coefficient vectors so use std::is_permutation
185  if (!std::is_permutation(
187  mooseError("All solid kinetic species must be added as secondary species");
188 
189  // Check that the size of property vectors is equal to the number of reactions
190  if (_logk.size() != _num_reactions)
191  mooseError("The number of values entered for log10_keq is not equal to the number of solid "
192  "kinetic reactions");
193  if (_r_area.size() != _num_reactions)
194  mooseError("The number of values entered for specific_reactive_surface_area is not equal to "
195  "the number of solid kinetic reactions");
196  if (_ref_kconst.size() != _num_reactions)
197  mooseError("The number of values entered for kinetic_rate_constant is not equal to the number "
198  "of solid kinetic reactions");
199  if (_e_act.size() != _num_reactions)
200  mooseError("The number of values entered for activation_energy is not equal to the number of "
201  "solid kinetic reactions");
202  if (_ref_temp.size() != _num_reactions)
203  mooseError("The number of values entered for reference_temperature is not equal to the number "
204  "of solid kinetic reactions");
205 }
206 
207 void
209 {
210  if (_current_task == "add_kernel")
211  {
212  // Add Kernels for each primary species
213  for (unsigned int i = 0; i < _primary_species.size(); ++i)
214  {
215  InputParameters params_kin = _factory.getValidParams("CoupledBEKinetic");
216  params_kin.set<NonlinearVariableName>("variable") = _primary_species[i];
217  params_kin.set<std::vector<Real>>("weight") = _weights[i];
218  params_kin.set<std::vector<VariableName>>("v") = _kinetic_species_involved[i];
219  _problem->addKernel("CoupledBEKinetic", _primary_species[i] + "_" + "_kin", params_kin);
220  }
221  }
222 
223  if (_current_task == "add_aux_kernel")
224  {
225  // Add AuxKernels for each solid kinetic species
226  for (unsigned int i = 0; i < _num_reactions; ++i)
227  {
228  InputParameters params_kin = _factory.getValidParams("KineticDisPreConcAux");
229  params_kin.set<AuxVariableName>("variable") = _solid_kinetic_species[i];
230  params_kin.defaultCoupledValue("log_k", _logk[i]);
231  params_kin.set<Real>("r_area") = _r_area[i];
232  params_kin.set<Real>("ref_kconst") = _ref_kconst[i];
233  params_kin.set<Real>("e_act") = _e_act[i];
234  params_kin.set<Real>("gas_const") = _gas_const;
235  params_kin.set<Real>("ref_temp") = _ref_temp[i];
236  params_kin.set<std::vector<VariableName>>("sys_temp") = _sys_temp;
237  params_kin.set<std::vector<Real>>("sto_v") = _stos[i];
238  params_kin.set<std::vector<VariableName>>("v") = _primary_species_involved[i];
239  _problem->addAuxKernel(
240  "KineticDisPreConcAux", "aux_" + _solid_kinetic_species[i], params_kin);
241  }
242  }
243 }
std::vector< std::vector< Real > > _stos
Stoichiometric coefficients for each primary species in each reaction.
const std::vector< Real > _ref_kconst
Reference kinetic rate constant.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::vector< std::vector< VariableName > > _primary_species_involved
Primary species involved in the ith kinetic reaction.
const std::vector< Real > _logk
Log10 of equilibrium constant.
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
const std::vector< VariableName > _sys_temp
Actual system temperature.
void addRequiredParam(const std::string &name, const std::string &doc_string)
AddCoupledSolidKinSpeciesAction(const InputParameters &params)
const std::vector< Real > _ref_temp
Reference temperature.
Factory & _factory
std::vector< std::string > _reactions
Vector of parsed reactions.
unsigned int _num_reactions
Number of reactions.
static InputParameters validParams()
std::vector< std::vector< VariableName > > _kinetic_species_involved
Secondary solid species involved the ith primary species.
Real defaultCoupledValue(const std::string &coupling_name, unsigned int i=0) const
T sign(T x)
const std::string & _current_task
const std::vector< Real > _r_area
Specific reactive surface area, m^2/L solution.
const Real _gas_const
Gas constant, (Default 8.314 J/mol/K)
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
const std::vector< AuxVariableName > _secondary_species
Secondary species added as AuxVariables.
const std::vector< NonlinearVariableName > _primary_species
Basis set of primary species.
const std::vector< Real > _e_act
Activation energy.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::string _input_reactions
Reaction network read from input file.
void mooseError(Args &&... args) const
std::vector< VariableName > _solid_kinetic_species
Secondary solid species read by the parser.
registerMooseAction("ChemicalReactionsApp", AddCoupledSolidKinSpeciesAction, "add_kernel")
void addClassDescription(const std::string &doc_string)
std::shared_ptr< FEProblemBase > & _problem
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const ConsoleStream _console
static const std::string k
Definition: NS.h:130
std::vector< std::vector< Real > > _weights
Weight of each primary species in each reaction.