19 "ramp_max_ionic_strength_subsequent",
21 "The number of iterations over which to progressively increase the maximum ionic strength "
22 "(from zero to max_ionic_strength) during time-stepping. Unless a great deal occurs in each "
23 "time step, this parameter can be set quite small");
24 params.
addParam<Real>(
"initial_temperature",
26 "Temperature at which the initial system is equilibrated. This is uniform "
27 "over the entire mesh.");
29 params.
addParam<Real>(
"close_system_at_time",
31 "Time at which to 'close' the entire spatial system, that is, change a "
32 "kg_solvent_water constraint to moles_bulk_water, and all free_molality "
33 "and free_moles_mineral_species to moles_bulk_species");
34 params.
addParam<std::vector<std::string>>(
35 "remove_fixed_activity_name",
37 "The name of the species that should have their activity or fugacity constraint removed at "
38 "time given in remove_fixed_activity_time. There should be an equal number of these names "
39 "as times given in remove_fixed_activity_time. Each of these must be in the basis and have "
40 "an activity or fugacity constraint");
41 params.
addParam<std::vector<Real>>(
"remove_fixed_activity_time",
43 "The times at which the species in remove_fixed_activity_name "
44 "should have their activity or fugacity constraint removed.");
45 params.
addParam<std::vector<std::string>>(
46 "source_species_names",
48 "The name of the species that are added at rates given in source_species_rates. There must "
49 "be an equal number of these as source_species_rates.");
51 "Rates, in mols/time_unit, of addition of the species with names given in "
52 "source_species_names. A negative value corresponds to removing a species: "
53 "be careful that you don't cause negative mass problems!");
54 params.
addParam<std::vector<std::string>>(
55 "controlled_activity_name",
57 "The names of the species that have their activity or fugacity constrained. There should be "
58 "an equal number of these names as values given in controlled_activity_value. NOTE: if "
59 "these species are not in the basis, or they do not have an activity (or fugacity) "
60 "constraint then their activity cannot be controlled: in this case MOOSE will ignore the "
61 "value you prescribe in controlled_activity_value.");
63 "Values of the activity or fugacity of the species in "
64 "controlled_activity_name list. These should always be positive");
66 "evaluate_kinetic_rates_always",
68 "If true, then, evaluate the kinetic rates at every Newton step during the solve using the "
69 "current values of molality, activity, etc (ie, implement an implicit solve). If false, "
70 "then evaluate the kinetic rates using the values of molality, activity, etc, at the start "
71 "of the current time step (ie, implement an explicit solve)");
72 params.
addParam<std::vector<std::string>>(
73 "kinetic_species_name",
75 "Names of the kinetic species given initial values in kinetic_species_initial_value");
77 "kinetic_species_initial_value",
79 "Initial number of moles, mass or volume (depending on kinetic_species_unit) for each of the "
80 "species named in kinetic_species_name");
81 MultiMooseEnum kin_species_unit(
"dimensionless moles molal kg g mg ug kg_per_kg_solvent "
82 "g_per_kg_solvent mg_per_kg_solvent ug_per_kg_solvent cm3");
84 "kinetic_species_unit",
86 "Units of the numerical values given in kinetic_species_initial_value. Moles: mole number. "
87 "kg: kilograms. g: grams. mg: milligrams. ug: micrograms. cm3: cubic centimeters");
88 params.
addParam<
bool>(
"adaptive_timestepping",
90 "Use adaptive timestepping at each node in an attempt to ensure "
91 "convergence of the solver. Setting this parameter to false saves some "
92 "compute time because copying of datastructures is avoided");
96 "If, during adaptive timestepping at a node, the time-step fails below this value, "
97 "MOOSE will give up trying to solve the geochemical system. Optimally, you should set this "
98 "value bearing abs_tol in mind because as dt changes, the initial value of the residual will "
99 "also typically change. For example, if you set dt_min very small relative to abs_tol MOOSE "
100 "may think the system has converged just because dt is small. Also, bear in mind your "
101 "typical timestep size: if dt_min < 1E-16*typical_dt then you will run out of precision");
105 "dt_dec >= 0 & dt_dec < 1.0",
106 "If a geochemical solve fails, then 'adpative timestepping' at the node is initiated "
107 "(assuming adaptive_timestepping = true): the time-step at the node is multiplied by this "
108 "amount, and the solve process re-tried");
113 "If a geochemical solve suceeds during adpative timestepping at a node, then the time-step "
114 "at the node is multiplied by this amount before performing the next adaptive timestep");
123 params.
addClassDescription(
"UserObject that controls the space-dependent and time-dependent "
124 "geochemistry reaction processes");
130 _initial_temperature(getParam<Real>(
"initial_temperature")),
131 _temperature(coupledValue(
"temperature")),
132 _num_kin(_mgd.kin_species_name.size()),
134 _mgd_at_node(_num_my_nodes, _mgd),
141 getParam<
std::vector<
std::string>>(
"swap_out_of_basis"),
142 getParam<
std::vector<
std::string>>(
"swap_into_basis"),
143 getParam<
std::string>(
"charge_balance_species"),
144 getParam<
std::vector<
std::string>>(
"constraint_species"),
145 getParam<
std::vector<Real>>(
"constraint_value"),
148 _initial_temperature,
149 getParam<unsigned>(
"extra_iterations_to_make_consistent"),
150 getParam<Real>(
"min_initial_molality"),
151 getParam<
std::vector<
std::string>>(
"kinetic_species_name"),
152 getParam<
std::vector<Real>>(
"kinetic_species_initial_value"),
154 _solver(_mgd.basis_species_name.size(),
155 _mgd.kin_species_name.size(),
157 getParam<Real>(
"abs_tol"),
158 getParam<Real>(
"rel_tol"),
159 getParam<unsigned>(
"max_iter"),
160 getParam<Real>(
"max_initial_residual"),
163 getParam<
std::vector<
std::string>>(
"prevent_precipitation"),
164 getParam<Real>(
"max_ionic_strength"),
165 getParam<unsigned>(
"ramp_max_ionic_strength_initial"),
166 getParam<bool>(
"evaluate_kinetic_rates_always")),
167 _close_system_at_time(getParam<Real>(
"close_system_at_time")),
168 _closed_system(false),
169 _source_species_names(getParam<
std::vector<
std::string>>(
"source_species_names")),
170 _num_source_species(_source_species_names.size()),
171 _source_species_rates(0),
172 _remove_fixed_activity_name(getParam<
std::vector<
std::string>>(
"remove_fixed_activity_name")),
173 _remove_fixed_activity_time(getParam<
std::vector<Real>>(
"remove_fixed_activity_time")),
174 _num_removed_fixed(_remove_fixed_activity_name.size()),
175 _removed_fixed_activity(_num_my_nodes,
std::vector<bool>(_num_removed_fixed, false)),
176 _controlled_activity_species_names(
177 getParam<
std::vector<
std::string>>(
"controlled_activity_name")),
178 _num_controlled_activity(_controlled_activity_species_names.size()),
179 _controlled_activity_species_values(0),
180 _mole_rates(_num_basis + _num_kin),
181 _mole_additions(_num_my_nodes, DenseVector<Real>(_num_basis + _num_kin)),
182 _dmole_additions(_num_my_nodes,
183 DenseMatrix<Real>(_num_basis + _num_kin, _num_basis + _num_kin)),
184 _ramp_subsequent(getParam<unsigned>(
"ramp_max_ionic_strength_subsequent")),
186 _execute_done(_num_my_nodes, false),
187 _adaptive_timestepping(getParam<bool>(
"adaptive_timestepping")),
188 _dt_min(_adaptive_timestepping ? getParam<Real>(
"dt_min") :
std::numeric_limits<Real>::max()),
189 _dt_dec(getParam<Real>(
"dt_dec")),
190 _dt_inc(getParam<Real>(
"dt_inc")),
200 getParam<std::vector<std::string>>(
"swap_out_of_basis"),
201 getParam<std::vector<std::string>>(
"swap_into_basis"),
202 getParam<std::string>(
"charge_balance_species"),
203 getParam<std::vector<std::string>>(
"constraint_species"),
204 getParam<std::vector<Real>>(
"constraint_value"),
205 getParam<MultiMooseEnum>(
"constraint_unit"),
206 getParam<MultiMooseEnum>(
"constraint_meaning"),
208 getParam<unsigned>(
"extra_iterations_to_make_consistent"),
209 getParam<Real>(
"min_initial_molality"),
210 getParam<std::vector<std::string>>(
"kinetic_species_name"),
211 getParam<std::vector<Real>>(
"kinetic_species_initial_value"),
212 getParam<MultiMooseEnum>(
"kinetic_species_unit")));
216 paramError(
"source_species_names",
"must have the same size as source_species_rates");
225 " does not appear in the basis, equilibrium or kinetic species list");
232 "remove_fixed_activity_name",
235 " is not in the basis, so cannot have its activity or fugacity constraint removed");
247 " is does not have an activity or fugacity constraint so cannot have such a "
248 "constraint removed");
253 "must be of the same size as remove_fixed_activity_time");
255 paramError(
"controlled_activity_name",
"must have the same size as controlled_activity_value");
261 for (
unsigned int i = 0; i < coupled_vars.size(); i++)
275 unsigned num_nodes_inserted = 0;
276 for (
const auto & node : as_range(msh.local_nodes_begin(), msh.local_nodes_end()))
282 "GeochemistrySpatialReactor: something wrong with node numbering in buildMyNodeNumber");
283 num_nodes_inserted += 1;
287 "GeochemistrySpatialReactor: something wrong with node numbering in buildMyNodeNumber");
321 "GeochemistrySpatialReactor: something wrong with node numbering in buildMyNodeNumber");
324 const unsigned aux_comp_number = 0;
326 _egs_at_node[my_node_number].getModelGeochemicalDatabase();
347 const std::vector<GeochemicalSystem::ConstraintMeaningEnum> & cm =
351 const unsigned basis_ind =
362 Real temperature0 =
_egs_at_node[my_node_number].getTemperature();
363 const Real temperature_rate = (
_temperature[aux_comp_number] - temperature0) /
_dt;
374 while (done_dt <
_dt)
390 for (
unsigned basis_ind = 0; basis_ind <
_num_basis; ++basis_ind)
400 Real temperature = temperature0 + my_dt * temperature_rate;
406 if (temperature !=
_egs_at_node[my_node_number].getTemperature())
408 _egs_at_node[my_node_number].setTemperature(temperature);
409 _egs_at_node[my_node_number].computeConsistentConfiguration();
425 temperature0 =
_egs_at_node[my_node_number].getTemperature();
439 "Geochemistry solve failed with dt = ", my_dt,
" at node: ",
_current_node->get_info());
442 if (done_dt + my_dt >
_dt)
443 my_dt =
_dt - done_dt;
482 for (
unsigned thrd = 1; thrd <
_nthreads; ++thrd)
484 std::vector<GeochemistrySpatialReactor *> objects;
488 .condition<AttribThread>(thrd)
491 mooseAssert(objects.size() == 1,
492 "GeochemistrySpatialReactor::finalize() failed to obtain a single thread copy of "
493 "the GeochemistrySpatialReactor");
503 mooseError(
"GeochemistrySpatialReactor cannot yet handle adaptive meshing");
526 mooseError(
"GeochemistrySpatialReactor does not know about node ", node_id);
530const DenseVector<Real> &
534 mooseError(
"GeochemistrySpatialReactor does not know about node ", node_id);
538const std::stringstream &
542 mooseError(
"GeochemistrySpatialReactor does not know about node ", node_id);
550 mooseError(
"GeochemistrySpatialReactor does not know about node ", node_id);
558 mooseError(
"GeochemistrySpatialReactor does not know about node ", node_id);
564 const std::string & )
const
registerMooseObject("GeochemistryApp", GeochemistrySpatialReactor)
virtual const VariableValue & coupledValue(const std::string &var_name, unsigned int comp=0) const
const std::vector< MooseVariableFieldBase * > & getCoupledMooseVars() const
unsigned int coupledComponents(const std::string &var_name) const
TheWarehouse & theWarehouse() const
void solveSystem(GeochemicalSystem &egs, std::stringstream &ss, unsigned &tot_iter, Real &abs_residual, Real dt, DenseVector< Real > &mole_additions, DenseMatrix< Real > &dmole_additions)
Solve the system.
void setRampMaxIonicStrength(unsigned ramp_max_ionic_strength)
Sets the value of _ramp_max_ionic_strength.
This class holds information about bulk composition, molalities, activities, activity coefficients,...
ConstraintMeaningEnum
Each basis species has one of the following constraints.
Base class that controls the spatio-temporal solution of geochemistry reactions.
virtual void finalize() override
std::vector< unsigned > _tot_iter
Number of iterations used by the solver at each node.
virtual void initialize() override
static InputParameters validParams()
GeochemistryIonicStrength _is
The ionic strength calculator.
const unsigned _num_my_nodes
Number of nodes handled by this processor (will need to be made un-const when mesh adaptivity is hand...
std::vector< Real > _abs_residual
L1norm of the solver residual at each node.
const unsigned _num_basis
number of basis species
GeochemistryActivityCoefficientsDebyeHuckel _gac
The activity calculator.
ModelGeochemicalDatabase _mgd
my copy of the underlying ModelGeochemicalDatabase
std::vector< std::stringstream > _solver_output
The solver output at each node.
GeochemistrySpeciesSwapper _swapper
The species swapper.
Class that controls the space-dependent and time-dependent geochemistry reactions.
unsigned _nthreads
number of threads used to execute this UserObject
virtual void initialize() override
std::vector< const VariableValue * > _source_species_rates
Rates of the source species.
virtual Real getMolesDumped(dof_id_type node_id, const std::string &species) const override
const Real _dt_min
minimum value of dt allowed during adpative timestepping. This is set to a large number if _adaptive_...
std::vector< GeochemicalSystem > _egs_at_node
GeochemicalSystem at each node.
GeochemicalSystem _egs_copy
GeochemicalSystem into which the nodal GeochemicalSystem is copied to enable recovery during adaptive...
std::unordered_map< dof_id_type, unsigned > _my_node_number
_my_node_number[_current_node->id()] = node number used in this object that corresponds to _current_n...
GeochemicalSolver _solver
The solver.
const Real _dt_inc
value to multiply dt my in the case of a successful solve
DenseVector< Real > _mole_rates
Rate of mole additions.
const VariableValue & _temperature
Temperature specified by user.
std::vector< bool > _execute_done
whether execute has been called using this thread
std::vector< DenseMatrix< Real > > _dmole_additions
Derivative of moles_added.
std::vector< DenseVector< Real > > _mole_additions
Moles of each basis species added at each node at the current timestep, along with kinetic rates.
virtual Real getSolverResidual(dof_id_type node_id) const override
std::vector< ModelGeochemicalDatabase > _mgd_at_node
ModelGeochemicalDatabase at each node.
virtual void finalize() override
the main-thread information is used to set the other-thread information in finalize()
std::vector< const VariableValue * > _controlled_activity_species_values
Activity or fugacity of the species with controlled activity or fugacity.
void buildMyNodeNumber()
Build the _my_node_number map.
static InputParameters sharedParams()
params that are shared with AddTimeDependentReactionSolverAction
const unsigned _num_kin
Number of kinetic species.
virtual void initialSetup() override
const bool _adaptive_timestepping
Whether to use adaptive timestepping at the nodes.
virtual unsigned getSolverIterations(dof_id_type node_id) const override
const Real _initial_temperature
Initial equilibration temperature.
const std::vector< Real > _remove_fixed_activity_time
Times at which to remove the fixed activity or fugacity from the species in _remove_fixed_activity_na...
const unsigned _num_removed_fixed
Number of elements in the vector _remove_fixed_activity_name;.
virtual void meshChanged() override
const std::vector< std::string > _remove_fixed_activity_name
Names of species to remove the fixed activity or fugacity constraint from.
virtual void execute() override
virtual const GeochemicalSystem & getGeochemicalSystem(dof_id_type node_id) const override
const Real _close_system_at_time
Defines the time at which to close the system.
const std::vector< std::string > _controlled_activity_species_names
Names of the species with controlled activity or fugacity.
const Real _dt_dec
value to multiply dt my in the case of a failed solve
GeochemistrySpatialReactor(const InputParameters ¶meters)
std::vector< std::vector< bool > > _removed_fixed_activity
Whether the activity or activity constraint has been removed at each node.
virtual void threadJoin(const UserObject &uo) override
virtual const std::stringstream & getSolverOutput(dof_id_type node_id) const override
const std::vector< std::string > _source_species_names
Names of the source species.
static InputParameters validParams()
const unsigned _num_controlled_activity
Number of species with controlled activity or fugacity.
const unsigned _num_source_species
Number of source species.
virtual const DenseVector< Real > & getMoleAdditions(dof_id_type node_id) const override
bool _closed_system
Whether the system has been closed.
const unsigned _ramp_subsequent
the ramp_max_ionic_strength to use during time-stepping
const std::string & name() const
void paramError(const std::string ¶m, Args... args) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
void addMooseVariableDependency(MooseVariableFieldBase *var)
const Node *const & _current_node
virtual MooseMesh & mesh()=0
FEProblemBase & _fe_problem
Data structure to hold all relevant information from the database file.
DenseMatrix< Real > eqm_stoichiometry
eqm_stoichiometry(i, j) = stoichiometric coefficient for equilibrium species "i" in terms of the basi...
std::unordered_map< std::string, unsigned > eqm_species_index
eqm_species_index[name] = index of the equilibrium species (secondary aqueous species,...
std::unordered_map< std::string, unsigned > basis_species_index
basis_species_index[name] = index of the basis species, within all ModelGeochemicalDatabase internal ...
std::unordered_map< std::string, unsigned > kin_species_index
kin_species_index[name] = index of the kinetic species, within all ModelGeochemicalDatabase internal ...