Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
AddGeochemistrySolverAction.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 
13 #include "NearestNodeNumber.h"
15 #include "BlockRestrictable.h"
16 #include "BoundaryRestrictable.h"
17 
18 registerMooseAction("GeochemistryApp", AddGeochemistrySolverAction, "add_output");
19 registerMooseAction("GeochemistryApp", AddGeochemistrySolverAction, "add_user_object");
20 registerMooseAction("GeochemistryApp",
22  "add_geochemistry_molality_aux");
23 
26 {
28  params.addParam<UserObjectName>(
29  "geochemistry_reactor_name",
30  "geochemistry_reactor",
31  "The name that will be given to the GeochemistryReactor UserObject built by this action");
32  params.addParam<bool>("include_moose_solve",
33  false,
34  "Include a usual MOOSE solve involving Variables and Kernels. In pure "
35  "reaction systems (without transport) include_moose_solve = false is "
36  "appropriate, but with transport 'true' must be used");
37 
38  params.addRequiredParam<UserObjectName>("model_definition",
39  "The name of the GeochemicalModelDefinition user object "
40  "(you must create this UserObject yourself)");
42 
45 
46  params.addRangeCheckedParam<Real>(
47  "stoichiometry_tolerance",
48  1E-6,
49  "stoichiometry_tolerance >= 0.0",
50  "Swapping involves inverting matrices via a singular value decomposition. During this "
51  "process: (1) if abs(singular value) < stoi_tol * L1norm(singular values), then the "
52  "matrix is deemed singular (so the basis swap is deemed invalid); (2) if abs(any "
53  "stoichiometric coefficient) < stoi_tol then it is set to zero.");
54 
55  // following are exclusively for the GeochemistryConsoleOutput
58  exec_enum = {EXEC_INITIAL, EXEC_FINAL};
59  params.addParam<ExecFlagEnum>(
60  "execute_console_output_on", exec_enum, "When to execute the geochemistry console output");
61  params.addParam<Point>("point",
62  Point(0.0, 0.0, 0.0),
63  "The geochemistry console output will be regarding the aqueous "
64  "solution at node that is closest to this point");
65 
66  // following are the Aux possibilities
67  params.addParam<bool>(
68  "add_aux_solvent_kg",
69  true,
70  "Add AuxVariable, called kg_solvent_H2O, that records the kg of solvent water");
71  params.addParam<bool>(
72  "add_aux_pH", true, "Add AuxVariable, called pH, that records the pH of solvent water");
73  params.addParam<bool>(
74  "add_aux_molal",
75  true,
76  "Add AuxVariables measured in molal units (ie mol(species)/kg(solvent_water)). These are "
77  "named molal_name, where 'name' is the species name. AuxVariables are added for all species "
78  "except minerals");
79  params.addParam<bool>("add_aux_mg_per_kg",
80  true,
81  "Add AuxVariables measured in mg(species)/kg(solvent_water). These are "
82  "named mg_per_kg_name, where 'name' is the species name. AuxVariables are "
83  "added for all species except minerals");
84  params.addParam<bool>("add_aux_free_mg",
85  true,
86  "Add AuxVariables for all minerals measured in free mg. These are named "
87  "free_mg_name, where 'name' is the species name");
88  params.addParam<bool>("add_aux_free_cm3",
89  true,
90  "Add AuxVariables for all minerals measured in free cm^3. These are named "
91  "free_cm3_name, where 'name' is the species name");
92  params.addParam<bool>(
93  "add_aux_activity",
94  true,
95  "Add AuxVariables that record the activity for all species (for gas species this equals the "
96  "gas fugacity). These are called activity_name where 'name' is the species name.");
97  params.addParam<bool>(
98  "add_aux_bulk_moles",
99  true,
100  "Add AuxVariables that record the number of bulk-composition moles for all species. Note "
101  "that these will be zero for any species not currently in the basis. These are called "
102  "bulk_moles_name where 'name' is the species name.");
103  params.addParam<bool>("add_aux_surface_charge",
104  true,
105  "Add AuxVariables, measured in C/m^2, corresponding to specific surface "
106  "charge for each mineral involved in surface sorption. These are "
107  "surface_charge_name, where 'name' is the mineral name");
108  params.addParam<bool>("add_aux_surface_potential",
109  true,
110  "Add AuxVariables, measured in V, corresponding to surface potential "
111  "for each mineral involved in surface sorption. These are "
112  "surface_potential_name, where 'name' is the mineral name");
113  params.addParam<bool>("add_aux_temperature",
114  true,
115  "Add AuxVariable, called solution_temperature, that records the "
116  "temperature of the aqueous solution in degC");
117  params.addParam<bool>(
118  "add_aux_kinetic_moles",
119  true,
120  "Add AuxVariables that record the number of moles for all kinetic species. These are called "
121  "moles_name where 'name' is the species name.");
122  params.addParam<bool>("add_aux_kinetic_additions",
123  true,
124  "Add AuxVariables that record the rate-of-change (-reaction_rate * dt) for "
125  "all kinetic species. These are called "
126  "mol_change_name where 'name' is the species name.");
127  params.addClassDescription("Base class for an Action that sets up a reaction solver. This class "
128  "adds a GeochemistryConsoleOutput and AuxVariables corresponding to "
129  "molalities, etc. Derived classes will create the solver.");
130 
131  return params;
132 }
133 
135  : Action(params)
136 {
137 }
138 
139 void
141 {
142  if (_current_task == "add_user_object" && isParamValid("execute_console_output_on"))
143  {
144  const std::string class_name = "NearestNodeNumberUO";
145  auto params = _factory.getValidParams(class_name);
146  params.set<Point>("point") = getParam<Point>("point");
147  if (isParamValid("block"))
148  params.set<std::vector<SubdomainName>>("block") =
149  getParam<std::vector<SubdomainName>>("block");
150  if (isParamValid("boundary"))
151  params.set<std::vector<BoundaryName>>("boundary") =
152  getParam<std::vector<BoundaryName>>("boundary");
153  params.set<ExecFlagEnum>("execute_on") = EXEC_INITIAL; // NOTE: adaptivity not active yet
154  _problem->addUserObject(class_name, "geochemistry_nearest_node_number", params);
155  }
156  else if (_current_task == "add_output" && isParamValid("execute_console_output_on"))
157  {
158  const std::string class_name = "GeochemistryConsoleOutput";
159  auto params = _factory.getValidParams(class_name);
160  params.set<UserObjectName>("geochemistry_reactor") =
161  getParam<UserObjectName>("geochemistry_reactor_name");
162  params.set<unsigned>("precision") = getParam<unsigned>("precision");
163  params.set<Real>("mol_cutoff") = getParam<Real>("mol_cutoff");
164  params.set<Real>("stoichiometry_tolerance") = getParam<Real>("stoichiometry_tolerance");
165  params.set<bool>("solver_info") = getParam<bool>("solver_info");
166  params.set<UserObjectName>("nearest_node_number_UO") = "geochemistry_nearest_node_number";
167  params.set<ExecFlagEnum>("execute_on") = getParam<ExecFlagEnum>("execute_console_output_on");
168  _problem->addOutput(class_name, "geochemistry_console_output", params);
169  }
170  else if (_current_task == "add_geochemistry_molality_aux")
171  {
173  ->getUserObject<GeochemicalModelDefinition>(
174  getParam<UserObjectName>("model_definition"))
175  .getDatabase();
176  // add temperature aux, if requested
177  if (getParam<bool>("add_aux_temperature"))
178  addAuxSpecies("solution_temperature", "H2O", "temperature");
179  // add water, if requested
180  if (getParam<bool>("add_aux_solvent_kg"))
181  addAuxSpecies("kg_solvent_H2O", "H2O", "molal");
182  if (getParam<bool>("add_aux_activity"))
183  addAuxSpecies("activity_H2O", "H2O", "activity");
184  if (getParam<bool>("add_aux_bulk_moles"))
185  addAuxSpecies("bulk_moles_H2O", "H2O", "bulk_moles");
186  // add pH, if requested
187  if (getParam<bool>("add_aux_pH"))
188  addAuxSpecies("pH", "H+", "neglog10a");
189 
190  // add the remaining ones
191  const unsigned num_basis = mgd.basis_species_name.size();
192  for (unsigned i = 1; i < num_basis; ++i)
193  {
194  if (getParam<bool>("add_aux_molal") && !mgd.basis_species_mineral[i])
195  addAuxSpecies("molal_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "molal");
196  if (getParam<bool>("add_aux_mg_per_kg") && !mgd.basis_species_mineral[i])
198  "mg_per_kg_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "mg_per_kg");
199  if (getParam<bool>("add_aux_free_cm3") && mgd.basis_species_mineral[i])
201  "free_cm3_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "free_cm3");
202  if (getParam<bool>("add_aux_free_mg") && mgd.basis_species_mineral[i])
203  addAuxSpecies("free_mg_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "free_mg");
204  if (getParam<bool>("add_aux_activity"))
206  "activity_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "activity");
207  if (getParam<bool>("add_aux_bulk_moles"))
209  "bulk_moles_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "bulk_moles");
210  }
211  const unsigned num_eqm = mgd.eqm_species_name.size();
212  for (unsigned j = 0; j < num_eqm; ++j)
213  {
214  if (getParam<bool>("add_aux_molal") && !mgd.eqm_species_mineral[j])
215  addAuxSpecies("molal_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "molal");
216  if (getParam<bool>("add_aux_mg_per_kg") && !mgd.eqm_species_mineral[j])
217  addAuxSpecies("mg_per_kg_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "mg_per_kg");
218  if (getParam<bool>("add_aux_free_cm3") && mgd.eqm_species_mineral[j])
219  addAuxSpecies("free_cm3_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "free_cm3");
220  if (getParam<bool>("add_aux_free_mg") && mgd.eqm_species_mineral[j])
221  addAuxSpecies("free_mg_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "free_mg");
222  if (getParam<bool>("add_aux_activity"))
223  addAuxSpecies("activity_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "activity");
224  if (getParam<bool>("add_aux_bulk_moles"))
226  "bulk_moles_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "bulk_moles");
227  }
228  // add the kinetic aux variables
229  const unsigned num_kin = mgd.kin_species_name.size();
230  for (unsigned k = 0; k < num_kin; ++k)
231  {
232  if (getParam<bool>("add_aux_free_cm3") && mgd.kin_species_mineral[k])
233  addAuxSpecies("free_cm3_" + mgd.kin_species_name[k], mgd.kin_species_name[k], "free_cm3");
234  if (getParam<bool>("add_aux_free_mg") && mgd.kin_species_mineral[k])
235  addAuxSpecies("free_mg_" + mgd.kin_species_name[k], mgd.kin_species_name[k], "free_mg");
236  if (getParam<bool>("add_aux_kinetic_moles"))
237  addAuxSpecies("moles_" + mgd.kin_species_name[k], mgd.kin_species_name[k], "kinetic_moles");
238  if (getParam<bool>("add_aux_kinetic_additions"))
240  "mol_change_" + mgd.kin_species_name[k], mgd.kin_species_name[k], "kinetic_additions");
241  }
242 
243  // add surface stuff
244  for (const auto & mineral : mgd.surface_sorption_name)
245  {
246  if (getParam<bool>("add_aux_surface_charge"))
247  addAuxSpecies("surface_charge_" + mineral, mineral, "surface_charge");
248  if (getParam<bool>("add_aux_surface_potential"))
249  addAuxSpecies("surface_potential_" + mineral, mineral, "surface_potential");
250  }
251  }
252 }
253 
254 void
255 AddGeochemistrySolverAction::addAuxSpecies(const std::string & var_name,
256  const std::string & species_name,
257  const std::string & quantity)
258 {
259  // add AuxVariable
260  auto var_params = _factory.getValidParams("MooseVariable");
261  _problem->addAuxVariable("MooseVariable", var_name, var_params);
262  // add AuxKernel
263  const std::string class_name = "GeochemistryQuantityAux";
264  auto params = _factory.getValidParams(class_name);
265  params.set<std::string>("species") = species_name;
266  params.set<MooseEnum>("quantity") = quantity;
267  params.set<UserObjectName>("reactor") = getParam<UserObjectName>("geochemistry_reactor_name");
268  params.set<AuxVariableName>("variable") = var_name;
269  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
270  _problem->addAuxKernel(class_name, var_name, params);
271 }
registerMooseAction("GeochemistryApp", AddGeochemistrySolverAction, "add_output")
std::vector< bool > kin_species_mineral
kin_species_mineral[j] = true iff the j^th kinetic species is a mineral
std::vector< std::string > surface_sorption_name
surface_sorption_name[k] = name of the mineral involved in surface sorption.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
static InputParameters validParams()
const ModelGeochemicalDatabase mgd
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
const ExecFlagType EXEC_TIMESTEP_END
static InputParameters sharedParams()
contains params that are shared with AddGeochemistrySolverAction and its children ...
void addRequiredParam(const std::string &name, const std::string &doc_string)
User object that parses a geochemical database file, and only retains information relevant to the cur...
static InputParameters sharedParams()
contains params that are shared with Actions that use this object
static InputParameters validParams()
ExecFlagEnum getDefaultExecFlagEnum()
bool isParamValid(const std::string &name) const
Factory & _factory
static InputParameters validParams()
const ModelGeochemicalDatabase & getDatabase() const
provides a reference to the pertinent geochemical database held by this object
AddGeochemistrySolverAction(const InputParameters &parameters)
const T & getParam(const std::string &name) const
const std::string & _current_task
static InputParameters validParams()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< bool > basis_species_mineral
basis_species_mineral[j] = true iff the j^th basis species is a mineral
std::shared_ptr< FEProblemBase > & _problem
std::vector< std::string > kin_species_name
kin_species_name[j] = name of the j^th kinetic species
Data structure to hold all relevant information from the database file.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
Action that sets up GeochemistryConsoleOutput and various AuxVariables.
std::vector< bool > eqm_species_mineral
eqm_species_mineral[i] = true iff the i^th equilibrium species is a mineral
const ExecFlagType EXEC_FINAL
std::vector< std::string > eqm_species_name
eqm_species_name[i] = name of the i^th eqm species
static const std::string k
Definition: NS.h:130
std::vector< std::string > basis_species_name
basis_species_name[j] = name of the j^th basis species
void addAuxSpecies(const std::string &var_name, const std::string &species_name, const std::string &unit)
Adds AuxVariable and AuxKernel that will record species concentrations.
const ExecFlagType EXEC_INITIAL