https://mooseframework.inl.gov
Loading...
Searching...
No Matches
GeochemistrySpatialReactor.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
13
16{
18 params.addParam<unsigned>(
19 "ramp_max_ionic_strength_subsequent",
20 0,
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",
25 25,
26 "Temperature at which the initial system is equilibrated. This is uniform "
27 "over the entire mesh.");
28 params.addCoupledVar("temperature", 25, "Temperature");
29 params.addParam<Real>("close_system_at_time",
30 0.0,
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",
36 {},
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",
42 {},
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",
47 {},
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.");
50 params.addCoupledVar("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",
56 {},
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.");
62 params.addCoupledVar("controlled_activity_value",
63 "Values of the activity or fugacity of the species in "
64 "controlled_activity_name list. These should always be positive");
65 params.addParam<bool>(
66 "evaluate_kinetic_rates_always",
67 true,
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",
74 {},
75 "Names of the kinetic species given initial values in kinetic_species_initial_value");
76 params.addParam<std::vector<Real>>(
77 "kinetic_species_initial_value",
78 {},
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",
85 kin_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",
89 false,
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");
93 params.addParam<Real>(
94 "dt_min",
95 1E-10,
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");
102 params.addRangeCheckedParam<Real>(
103 "dt_dec",
104 0.5,
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");
109 params.addRangeCheckedParam<Real>(
110 "dt_inc",
111 1.1,
112 "dt_inc >= 1.0",
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");
115 return params;
116}
117
120{
123 params.addClassDescription("UserObject that controls the space-dependent and time-dependent "
124 "geochemistry reaction processes");
125 return params;
126}
127
129 : GeochemistryReactorBase(parameters),
130 _initial_temperature(getParam<Real>("initial_temperature")),
131 _temperature(coupledValue("temperature")),
132 _num_kin(_mgd.kin_species_name.size()),
133 // NOTE: initialize _mgd_at_node before the swaps are performed
134 _mgd_at_node(_num_my_nodes, _mgd),
135 _egs_at_node(),
136 // NOTE: the following implements the swaps in _mgd
137 _egs_copy(_mgd,
138 _gac,
139 _is,
140 _swapper,
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"),
146 getParam<MultiMooseEnum>("constraint_unit"),
147 getParam<MultiMooseEnum>("constraint_meaning"),
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"),
153 getParam<MultiMooseEnum>("kinetic_species_unit")),
154 _solver(_mgd.basis_species_name.size(),
155 _mgd.kin_species_name.size(),
156 _is,
157 getParam<Real>("abs_tol"),
158 getParam<Real>("rel_tol"),
159 getParam<unsigned>("max_iter"),
160 getParam<Real>("max_initial_residual"),
161 _small_molality,
162 _max_swaps_allowed,
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")),
185 _my_node_number(),
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")),
191 _nthreads(1)
192{
193 // build _egs_at_node
194 for (unsigned i = 0; i < _num_my_nodes; ++i)
195 _egs_at_node.push_back(
197 _gac,
198 _is,
199 _swapper,
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")));
213
214 // check sources and set the rates
215 if (coupledComponents("source_species_rates") != _num_source_species)
216 paramError("source_species_names", "must have the same size as source_species_rates");
217 for (unsigned i = 0; i < _num_source_species; ++i)
218 _source_species_rates.push_back(&coupledValue("source_species_rates", i));
219 for (unsigned i = 0; i < _num_source_species; ++i)
220 if (!(_mgd.basis_species_index.count(_source_species_names[i]) == 1 ||
223 paramError("source_species_names",
224 "The name " + _source_species_names[i] +
225 " does not appear in the basis, equilibrium or kinetic species list");
226
227 // check and set activity controllers
228 for (unsigned i = 0; i < _num_removed_fixed; ++i)
229 {
232 "remove_fixed_activity_name",
233 "The species ",
235 " is not in the basis, so cannot have its activity or fugacity constraint removed");
236 else if (_num_my_nodes >
237 0) // don't consider the silly (but possible) case that there are no nodes
238 {
239 const unsigned basis_ind = _mgd.basis_species_index.at(_remove_fixed_activity_name[i]);
241 _egs_at_node[0].getConstraintMeaning()[basis_ind];
244 paramError("remove_fixed_activity_name",
245 "The species ",
247 " is does not have an activity or fugacity constraint so cannot have such a "
248 "constraint removed");
249 }
250 }
252 paramError("remove_fixed_activity_name",
253 "must be of the same size as remove_fixed_activity_time");
254 if (coupledComponents("controlled_activity_value") != _num_controlled_activity)
255 paramError("controlled_activity_name", "must have the same size as controlled_activity_value");
256 for (unsigned i = 0; i < _num_controlled_activity; ++i)
257 _controlled_activity_species_values.push_back(&coupledValue("controlled_activity_value", i));
258
259 // record coupled variables
260 const std::vector<MooseVariableFEBase *> & coupled_vars = getCoupledMooseVars();
261 for (unsigned int i = 0; i < coupled_vars.size(); i++)
262 addMooseVariableDependency(coupled_vars[i]);
263
265}
266
267void
269{
270 const MeshBase & msh = _subproblem.mesh().getMesh();
271
272 // create the map from MOOSE's node numbering to the local node numbering (_my_node_number) used
273 // by this object
274 _my_node_number.clear();
275 unsigned num_nodes_inserted = 0;
276 for (const auto & node : as_range(msh.local_nodes_begin(), msh.local_nodes_end()))
277 {
278 if (_my_node_number.count(node->id()) == 0)
279 _my_node_number[node->id()] = num_nodes_inserted;
280 else
282 "GeochemistrySpatialReactor: something wrong with node numbering in buildMyNodeNumber");
283 num_nodes_inserted += 1;
284 }
285 mooseAssert(
287 "GeochemistrySpatialReactor: something wrong with node numbering in buildMyNodeNumber");
288}
289
290void
292{
293 // Solve the geochemical system with its initial composition and with dt=0 so no kinetic additions
294 for (unsigned i = 0; i < _num_my_nodes; ++i)
295 {
296 _mole_additions[i].zero();
297 _dmole_additions[i].zero();
300 _tot_iter[i],
301 _abs_residual[i],
302 0.0,
305 }
306}
307
308void
315
316void
318{
319 if (_my_node_number.count(_current_node->id()) == 0)
321 "GeochemistrySpatialReactor: something wrong with node numbering in buildMyNodeNumber");
322 const unsigned my_node_number = _my_node_number.at(_current_node->id());
323
324 const unsigned aux_comp_number = 0; // component number to use for AuxVariables
325 const ModelGeochemicalDatabase & mgd_ref =
326 _egs_at_node[my_node_number].getModelGeochemicalDatabase();
327
328 // close system
330 _egs_at_node[my_node_number].closeSystem();
331
332 // remove fixed-activity constraints.
333 for (unsigned i = 0; i < _num_removed_fixed; ++i)
334 {
335 if (!_removed_fixed_activity[my_node_number][i] && _t >= _remove_fixed_activity_time[i])
336 {
338 _egs_at_node[my_node_number].changeConstraintToBulk(
340 _removed_fixed_activity[my_node_number][i] = true;
341 }
342 }
343
344 // control activity
345 for (unsigned ca = 0; ca < _num_controlled_activity; ++ca)
346 {
347 const std::vector<GeochemicalSystem::ConstraintMeaningEnum> & cm =
348 _egs_at_node[my_node_number].getConstraintMeaning();
350 {
351 const unsigned basis_ind =
355 _egs_at_node[my_node_number].setConstraintValue(
356 basis_ind, (*_controlled_activity_species_values[ca])[aux_comp_number]);
357 }
358 }
359
361
362 Real temperature0 = _egs_at_node[my_node_number].getTemperature();
363 const Real temperature_rate = (_temperature[aux_comp_number] - temperature0) / _dt;
364
365 // record the system in case of solve failures using the copy-assignment operator of
366 // GeochemicalSystem
368 _egs_copy = _egs_at_node[my_node_number];
369
370 Real done_dt = 0.0;
371 Real my_dt = _dt;
372
373 // the following loop implements adaptive timestepping at the node
374 while (done_dt < _dt)
375 {
376 // compute moles added in the current basis (the basis might change during adaptive
377 // timestepping)
378 _mole_rates.zero();
379 for (unsigned i = 0; i < _num_source_species; ++i)
380 {
381 const Real this_rate = (*_source_species_rates[i])[aux_comp_number];
382 if (mgd_ref.basis_species_index.count(_source_species_names[i]))
383 {
384 const unsigned basis_ind = mgd_ref.basis_species_index.at(_source_species_names[i]);
385 _mole_rates(basis_ind) += this_rate;
386 }
387 else if (mgd_ref.eqm_species_index.count(_source_species_names[i]))
388 {
389 const unsigned eqm_j = mgd_ref.eqm_species_index.at(_source_species_names[i]);
390 for (unsigned basis_ind = 0; basis_ind < _num_basis; ++basis_ind)
391 _mole_rates(basis_ind) += mgd_ref.eqm_stoichiometry(eqm_j, basis_ind) * this_rate;
392 }
393 else
394 {
395 const unsigned kin_ind = mgd_ref.kin_species_index.at(_source_species_names[i]);
396 _mole_rates(_num_basis + kin_ind) += this_rate;
397 }
398 }
399
400 Real temperature = temperature0 + my_dt * temperature_rate;
401 for (unsigned i = 0; i < _num_basis + _num_kin; ++i)
402 _mole_additions[my_node_number](i) = my_dt * _mole_rates(i);
403 _dmole_additions[my_node_number].zero();
404
405 // set temperature, if needed
406 if (temperature != _egs_at_node[my_node_number].getTemperature())
407 {
408 _egs_at_node[my_node_number].setTemperature(temperature);
409 _egs_at_node[my_node_number].computeConsistentConfiguration();
410 }
411
412 // solve the geochemical system
413 try
414 {
415 _solver.solveSystem(_egs_at_node[my_node_number],
416 _solver_output[my_node_number],
417 _tot_iter[my_node_number],
418 _abs_residual[my_node_number],
419 my_dt,
420 _mole_additions[my_node_number],
421 _dmole_additions[my_node_number]);
422 done_dt += my_dt;
423 if (done_dt < _dt)
424 {
425 temperature0 = _egs_at_node[my_node_number].getTemperature();
426 _egs_copy =
427 _egs_at_node[my_node_number]; // use the copy-assignment operator of GeochemicalSystem
428 }
429 my_dt *= _dt_inc;
430 }
431 catch (const MooseException & e)
432 {
433 // use the copy-assignment operator of GeochemicalSystem to restore to the original
435 _egs_at_node[my_node_number] = _egs_copy;
436 my_dt *= _dt_dec;
437 if (my_dt < _dt_min)
438 mooseException(
439 "Geochemistry solve failed with dt = ", my_dt, " at node: ", _current_node->get_info());
440 }
441
442 if (done_dt + my_dt > _dt)
443 my_dt = _dt - done_dt; // avoid overstepping
444 }
445
446 _execute_done[my_node_number] = true;
447}
448
449void
451{
452 _nthreads += 1;
453 const auto & gsr = static_cast<const GeochemistrySpatialReactor &>(uo);
454 for (unsigned i = 0; i < _num_my_nodes; ++i)
455 {
456 if (!_execute_done[i] && gsr._execute_done[i])
457 {
458 _solver_output[i].str("");
459 _solver_output[i] << gsr._solver_output[i].str();
460 _tot_iter[i] = gsr._tot_iter[i];
461 _abs_residual[i] = gsr._abs_residual[i];
462 _mole_additions[i] = gsr._mole_additions[i];
463 _egs_at_node[i] = gsr._egs_at_node[i];
464 _removed_fixed_activity[i] = gsr._removed_fixed_activity[i];
465 // _mgd_at_node does not need to be threadJoined, because _egs_at_node[i] =
466 // gsr._egs_at_node[i] uses the copy-assignment operator to copy the data in
467 // _egs_at_node[i]._mgd
468 }
469 }
470}
471
472void
474{
476 // if relevant, record that system is closed
478 _closed_system = true;
479 // ensure that the non-main threads have the main-thread's copy of _egs_at_node (and hence
480 // _mgd_at_node) and _removed_fixed_activity, since the main-thread's copy has correctly gathered
481 // all the information during threadJoin
482 for (unsigned thrd = 1; thrd < _nthreads; ++thrd)
483 {
484 std::vector<GeochemistrySpatialReactor *> objects;
486 .query()
487 .condition<AttribSystem>("UserObject")
488 .condition<AttribThread>(thrd)
489 .condition<AttribName>(name())
490 .queryInto(objects);
491 mooseAssert(objects.size() == 1,
492 "GeochemistrySpatialReactor::finalize() failed to obtain a single thread copy of "
493 "the GeochemistrySpatialReactor");
494 objects[0]->_removed_fixed_activity = _removed_fixed_activity;
495 objects[0]->_egs_at_node = _egs_at_node;
496 objects[0]->_closed_system = _closed_system;
497 }
498}
499
500void
502{
503 mooseError("GeochemistrySpatialReactor cannot yet handle adaptive meshing");
504 /*
505Note to future coders:
506- have to rebuild _my_node_number. _num_my_nodes has to be changed (so its not const anymore).
507The Action must not just execute_on = EXEC_INITIAL for NearestNodeNumberUO
508- have to populate the new nodes correctly. This might be easiest if, at the start of execute,
509_egs_at_node was always populated using AuxVariables (probably a RequiredCoupledVar that is
510actually a ArrayVariableValue & (constructed with coupledArrayValue instead of just coupledValue)
511that record the kg_solvent_water, free molality, surface_pot_expr, etc. That is use
512_egs_at_node[i].setSolventMassAndFreeMolalityAndMineralMolesAndSurfacePotsAndKineticMoles with the
513values from the AuxVariables. The reason for this design is that then MOOSE handles the
514interpolation of the AuxVariables to the newly-created nodes during mesh adaptivity. The
515difficult thing is to figure out the variables at the new nodes. Probably should copy the basis
516species, swap stuff, etc (_mgd_at_node) from the nearest original node to the newly-created node.
517And then solve the new system to allow basis swaps if appropriate. This is a bit tricky, hence it
518hasn't yet been implemented.
519 */
520}
521
522const GeochemicalSystem &
524{
525 if (_my_node_number.count(node_id) != 1)
526 mooseError("GeochemistrySpatialReactor does not know about node ", node_id);
527 return _egs_at_node[_my_node_number.at(node_id)];
528}
529
530const DenseVector<Real> &
532{
533 if (_my_node_number.count(node_id) != 1)
534 mooseError("GeochemistrySpatialReactor does not know about node ", node_id);
535 return _mole_additions[_my_node_number.at(node_id)];
536}
537
538const std::stringstream &
540{
541 if (_my_node_number.count(node_id) != 1)
542 mooseError("GeochemistrySpatialReactor does not know about node ", node_id);
543 return _solver_output[_my_node_number.at(node_id)];
544}
545
546unsigned
548{
549 if (_my_node_number.count(node_id) != 1)
550 mooseError("GeochemistrySpatialReactor does not know about node ", node_id);
551 return _tot_iter[_my_node_number.at(node_id)];
552}
553
554Real
556{
557 if (_my_node_number.count(node_id) != 1)
558 mooseError("GeochemistrySpatialReactor does not know about node ", node_id);
559 return _abs_residual[_my_node_number.at(node_id)];
560}
561
562Real
564 const std::string & /*species*/) const
565{
566 return 0.0;
567}
registerMooseObject("GeochemistryApp", GeochemistrySpatialReactor)
InputParameters emptyInputParameters()
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
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.
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;.
const std::vector< std::string > _remove_fixed_activity_name
Names of species to remove the fixed activity or fugacity constraint from.
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 &parameters)
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.
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
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)
void addCoupledVar(const std::string &name, const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const std::string & name() const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
MeshBase & getMesh()
void addMooseVariableDependency(MooseVariableFieldBase *var)
const Node *const & _current_node
virtual MooseMesh & mesh()=0
Query query()
SubProblem & _subproblem
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 ...