https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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"
17
18registerMooseAction("GeochemistryApp", AddGeochemistrySolverAction, "add_output");
19registerMooseAction("GeochemistryApp", AddGeochemistrySolverAction, "add_user_object");
20registerMooseAction("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
138
139void
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
254void
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")
const ModelGeochemicalDatabase mgd
const ExecFlagType EXEC_TIMESTEP_END
const ExecFlagType EXEC_INITIAL
const ExecFlagType EXEC_FINAL
static InputParameters validParams()
std::shared_ptr< FEProblemBase > & _problem
const std::string & _current_task
Action that sets up GeochemistryConsoleOutput and various AuxVariables.
AddGeochemistrySolverAction(const InputParameters &parameters)
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.
static InputParameters validParams()
static InputParameters validParams()
InputParameters getValidParams(const std::string &name) const
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 sharedParams()
contains params that are shared with AddGeochemistrySolverAction and its children
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)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const T & getParam(const std::string &name) const
bool isParamValid(const std::string &name) const
Factory & _factory
ExecFlagEnum getDefaultExecFlagEnum()
Data structure to hold all relevant information from the database file.
std::vector< bool > eqm_species_mineral
eqm_species_mineral[i] = true iff the i^th equilibrium species is a mineral
std::vector< bool > kin_species_mineral
kin_species_mineral[j] = true iff the j^th kinetic species is a mineral
std::vector< std::string > kin_species_name
kin_species_name[j] = name of the j^th kinetic species
std::vector< bool > basis_species_mineral
basis_species_mineral[j] = true iff the j^th basis species is a mineral
std::vector< std::string > basis_species_name
basis_species_name[j] = name of the j^th basis species
std::vector< std::string > surface_sorption_name
surface_sorption_name[k] = name of the mineral involved in surface sorption.
std::vector< std::string > eqm_species_name
eqm_species_name[i] = name of the i^th eqm species