https://mooseframework.inl.gov
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");
83  params.addParam<MultiMooseEnum>(
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  {
231  paramError(
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 
267 void
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
281  mooseError(
282  "GeochemistrySpatialReactor: something wrong with node numbering in buildMyNodeNumber");
283  num_nodes_inserted += 1;
284  }
285  mooseAssert(
286  _my_node_number.size() == _num_my_nodes,
287  "GeochemistrySpatialReactor: something wrong with node numbering in buildMyNodeNumber");
288 }
289 
290 void
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();
299  _solver_output[i],
300  _tot_iter[i],
301  _abs_residual[i],
302  0.0,
303  _mole_additions[i],
304  _dmole_additions[i]);
305  }
306 }
307 
308 void
310 {
312  _execute_done.assign(_num_my_nodes, false);
313  _nthreads = 1;
314 }
315 
316 void
318 {
319  if (_my_node_number.count(_current_node->id()) == 0)
320  mooseError(
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  {
337  if (mgd_ref.basis_species_index.count(_remove_fixed_activity_name[i]))
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 
449 void
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 
472 void
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 
500 void
502 {
503  mooseError("GeochemistrySpatialReactor cannot yet handle adaptive meshing");
504  /*
505 Note to future coders:
506 - have to rebuild _my_node_number. _num_my_nodes has to be changed (so its not const anymore).
507 The 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
510 actually a ArrayVariableValue & (constructed with coupledArrayValue instead of just coupledValue)
511 that record the kg_solvent_water, free molality, surface_pot_expr, etc. That is use
512 _egs_at_node[i].setSolventMassAndFreeMolalityAndMineralMolesAndSurfacePotsAndKineticMoles with the
513 values from the AuxVariables. The reason for this design is that then MOOSE handles the
514 interpolation of the AuxVariables to the newly-created nodes during mesh adaptivity. The
515 difficult thing is to figure out the variables at the new nodes. Probably should copy the basis
516 species, swap stuff, etc (_mgd_at_node) from the nearest original node to the newly-created node.
517 And then solve the new system to allow basis swaps if appropriate. This is a bit tricky, hence it
518 hasn't yet been implemented.
519  */
520 }
521 
522 const 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 
530 const 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 
538 const 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 
546 unsigned
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 
554 Real
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 
562 Real
564  const std::string & /*species*/) const
565 {
566  return 0.0;
567 }
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.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
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.
static const std::string temperature
Definition: NS.h:59
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
InputParameters emptyInputParameters()
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)
SubProblem & _subproblem
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() ...
MeshBase & getMesh()
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 &param, 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
void addCoupledVar(const std::string &name, const std::string &doc_string)
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 &parameters)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< Real > _abs_residual
L1norm of the solver residual at each node.
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.
Query query()
This class holds information about bulk composition, molalities, activities, activity coefficients...
void mooseError(Args &&... args) const
GeochemistrySpeciesSwapper _swapper
The species swapper.
virtual unsigned getSolverIterations(dof_id_type node_id) const override
void addClassDescription(const std::string &doc_string)
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.
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
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.
uint8_t dof_id_type
const std::vector< std::string > _remove_fixed_activity_name
Names of species to remove the fixed activity or fugacity constraint from.