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");
26 "Temperature at which the initial system is equilibrated. This is uniform " 27 "over the entire mesh.");
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 =
374 while (done_dt <
_dt)
390 for (
unsigned basis_ind = 0; basis_ind <
_num_basis; ++basis_ind)
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);
530 const DenseVector<Real> &
534 mooseError(
"GeochemistrySpatialReactor does not know about node ", node_id);
538 const 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 const unsigned _num_basis
number of basis species
virtual MooseMesh & mesh()=0
virtual void threadJoin(const UserObject &uo) override
Class that controls the space-dependent and time-dependent geochemistry reactions.
virtual void finalize() override
const Real _close_system_at_time
Defines the time at which to close the system.
const unsigned _ramp_subsequent
the ramp_max_ionic_strength to use during time-stepping
static InputParameters validParams()
void buildMyNodeNumber()
Build the _my_node_number map.
std::vector< unsigned > _tot_iter
Number of iterations used by the solver at each node.
const unsigned _num_controlled_activity
Number of species with controlled activity or fugacity.
virtual void initialSetup() override
virtual const std::stringstream & getSolverOutput(dof_id_type node_id) const override
std::vector< const VariableValue * > _source_species_rates
Rates of the source species.
ModelGeochemicalDatabase _mgd
my copy of the underlying ModelGeochemicalDatabase
std::vector< DenseMatrix< Real > > _dmole_additions
Derivative of moles_added.
std::unordered_map< std::string, unsigned > basis_species_index
basis_species_index[name] = index of the basis species, within all ModelGeochemicalDatabase internal ...
GeochemicalSolver _solver
The solver.
const Node *const & _current_node
const Real _initial_temperature
Initial equilibration temperature.
std::unordered_map< std::string, unsigned > eqm_species_index
eqm_species_index[name] = index of the equilibrium species (secondary aqueous species, redox couples in equilibrium with the aqueous solution, minerals in equilibrium with the aqueous solution, gases in equilibrium with the aqueous solution) within all ModelGeochemicalDatabase internal datastrcutres, with given name
DenseVector< Real > _mole_rates
Rate of mole additions.
virtual void execute() override
static const std::string temperature
const bool _adaptive_timestepping
Whether to use adaptive timestepping at the nodes.
registerMooseObject("GeochemistryApp", GeochemistrySpatialReactor)
virtual const std::string & name() const
virtual Real getSolverResidual(dof_id_type node_id) const override
virtual Real getMolesDumped(dof_id_type node_id, const std::string &species) const override
std::unordered_map< std::string, unsigned > kin_species_index
kin_species_index[name] = index of the kinetic species, within all ModelGeochemicalDatabase internal ...
auto max(const L &left, const R &right)
unsigned _nthreads
number of threads used to execute this UserObject
DenseMatrix< Real > eqm_stoichiometry
eqm_stoichiometry(i, j) = stoichiometric coefficient for equilibrium species "i" in terms of the basi...
static InputParameters validParams()
ConstraintMeaningEnum
Each basis species has one of the following constraints.
virtual const VariableValue & coupledValue(const std::string &var_name, unsigned int comp=0) const
const unsigned _num_my_nodes
Number of nodes handled by this processor (will need to be made un-const when mesh adaptivity is hand...
virtual void finalize() override
the main-thread information is used to set the other-thread information in finalize() ...
const VariableValue & _temperature
Temperature specified by user.
TheWarehouse & theWarehouse() const
std::vector< std::stringstream > _solver_output
The solver output at each node.
const Real _dt_inc
value to multiply dt my in the case of a successful solve
std::vector< std::vector< bool > > _removed_fixed_activity
Whether the activity or activity constraint has been removed at each node.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
const unsigned _num_source_species
Number of source species.
const T & getParam(const std::string &name) const
const unsigned _num_kin
Number of kinetic species.
void paramError(const std::string ¶m, Args... args) 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.
GeochemicalSystem _egs_copy
GeochemicalSystem into which the nodal GeochemicalSystem is copied to enable recovery during adaptive...
const Real _dt_dec
value to multiply dt my in the case of a failed solve
std::vector< GeochemicalSystem > _egs_at_node
GeochemicalSystem at each node.
virtual void initialize() override
virtual const DenseVector< Real > & getMoleAdditions(dof_id_type node_id) const override
const std::vector< MooseVariableFieldBase *> & getCoupledMooseVars() const
unsigned int coupledComponents(const std::string &var_name) const
std::vector< const VariableValue * > _controlled_activity_species_values
Activity or fugacity of the species with controlled activity or fugacity.
void addMooseVariableDependency(MooseVariableFieldBase *var)
GeochemistryIonicStrength _is
The ionic strength calculator.
GeochemistrySpatialReactor(const InputParameters ¶meters)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< Real > _abs_residual
L1norm of the solver residual at each node.
virtual void initialize() override
FEProblemBase & _fe_problem
static InputParameters sharedParams()
params that are shared with AddTimeDependentReactionSolverAction
std::vector< bool > _execute_done
whether execute has been called using this thread
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...
void mooseError(Args &&... args) const
GeochemistrySpeciesSwapper _swapper
The species swapper.
virtual void meshChanged() override
virtual unsigned getSolverIterations(dof_id_type node_id) const override
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...
Data structure to hold all relevant information from the database file.
const std::vector< std::string > _controlled_activity_species_names
Names of the species with controlled activity or fugacity.
bool _closed_system
Whether the system has been closed.
virtual const GeochemicalSystem & getGeochemicalSystem(dof_id_type node_id) const override
Base class that controls the spatio-temporal solution of geochemistry reactions.
const unsigned _num_removed_fixed
Number of elements in the vector _remove_fixed_activity_name;.
std::vector< DenseVector< Real > > _mole_additions
Moles of each basis species added at each node at the current timestep, along with kinetic rates...
const Real _dt_min
minimum value of dt allowed during adpative timestepping. This is set to a large number if _adaptive_...
GeochemistryActivityCoefficientsDebyeHuckel _gac
The activity calculator.
const std::vector< std::string > _source_species_names
Names of the source species.
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...
std::vector< ModelGeochemicalDatabase > _mgd_at_node
ModelGeochemicalDatabase at each node.
const std::vector< std::string > _remove_fixed_activity_name
Names of species to remove the fixed activity or fugacity constraint from.