https://mooseframework.inl.gov
GeochemistryQuantityAux.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.addClassDescription(
19  "Extracts information from the Reactor and records it in the AuxVariable");
20  params.addRequiredParam<std::string>("species", "Species name");
21  MooseEnum quantity_choice("molal mg_per_kg free_mg free_cm3 neglog10a activity bulk_moles "
22  "surface_charge surface_potential temperature kinetic_moles "
23  "kinetic_additions moles_dumped transported_moles_in_original_basis",
24  "molal");
25  params.addParam<MooseEnum>(
26  "quantity",
27  quantity_choice,
28  "Type of quantity to output. These are available for non-kinetic species: activity (which "
29  "equals "
30  "fugacity for gases); bulk moles (this will be zero if the species is not in the basis); "
31  "neglog10a = -log10(activity); transported_moles_in_original_basis (will throw an error if "
32  "species is not in original basis). These are available only for non-kinetic non-minerals: "
33  "molal = "
34  "mol(species)/kg(solvent_water); mg_per_kg = mg(species)/kg(solvent_water). These are "
35  "available only for minerals: "
36  "free_mg = free mg; free_cm3 = free cubic-centimeters; moles_dumped = moles dumped when "
37  "special dump and flow-through modes are active. These are available for minerals "
38  "that host sorbing sites: surface_charge (C/m^2); surface_potential (V). These are "
39  "available for kinetic species: kinetic_moles; kinetic_additions (-dt * rate = mole "
40  "increment in kinetic species for this timestep). If "
41  "quantity=temperature, then the 'species' is ignored and the AuxVariable will record the "
42  "aqueous solution temperature in degC");
43  params.addRequiredParam<UserObjectName>("reactor",
44  "The name of the Geochemistry*Reactor user object.");
45  params.declareControllable("species");
46  return params;
47 }
48 
50  : AuxKernel(parameters),
51  _species(getParam<std::string>("species")),
52  _reactor(getUserObject<GeochemistryReactorBase>("reactor")),
53  _quantity_choice(getParam<MooseEnum>("quantity").getEnum<QuantityChoiceEnum>()),
54  _surface_sorption_mineral_index(0)
55 {
58  if (!(mgd.basis_species_index.count(_species) == 1 ||
59  mgd.eqm_species_index.count(_species) == 1 || mgd.kin_species_index.count(_species) == 1))
60  paramError(
61  "species",
62  _species,
63  " does not appear in the model's geochemical system either as a basis or equilibrium "
64  "or kinetic species, but you requested an Aux involving it");
65 
66  bool is_mineral = false;
67  if (mgd.basis_species_index.count(_species) == 1)
69  else if (mgd.eqm_species_index.count(_species) == 1)
71  else
73  bool is_kinetic = (mgd.kin_species_index.count(_species) == 1);
74 
75  if (!is_mineral && (_quantity_choice == QuantityChoiceEnum::FREE_CM3 ||
80  paramError(
81  "quantity",
82  "the free_mg, free_cm3, moles_dumped and surface-related quantities are only available for "
83  "mineral species");
84  if ((is_mineral || is_kinetic) && (_quantity_choice == QuantityChoiceEnum::MOLAL ||
86  paramError("quantity",
87  "the molal and mg_per_kg quantities are only available for "
88  "non-kinetic, non-mineral species");
91  {
92  _surface_sorption_mineral_index = std::distance(
93  mgd.surface_sorption_name.begin(),
94  std::find(mgd.surface_sorption_name.begin(), mgd.surface_sorption_name.end(), _species));
96  paramError("species",
97  "cannot record surface charge or surface potential for a species that is not "
98  "involved in surface sorption");
99  }
100  if (!is_kinetic && (_quantity_choice == QuantityChoiceEnum::KINETIC_MOLES ||
102  paramError("quantity",
103  "the kinetic_moles and kinetic_additions quantities are only available for kinetic "
104  "species");
105  if (is_kinetic && (_quantity_choice == QuantityChoiceEnum::NEGLOG10A ||
108  paramError("species", "cannot record activity, neglog10a or bulk_moles for a kinetic species");
111  _species); // will throw error if species not in original basis
112 }
113 
114 Real
116 {
117  Real ret = 0.0;
126  ret = egs.getTemperature();
131  else
132  {
133  if (mgd.basis_species_index.count(_species) == 1)
134  {
135  const unsigned basis_ind = mgd.basis_species_index.at(_species);
136  switch (_quantity_choice)
137  {
139  ret = egs.getSolventMassAndFreeMolalityAndMineralMoles()[basis_ind] *
140  mgd.basis_species_molecular_weight[basis_ind] * 1000.0;
141  break;
143  ret = egs.getSolventMassAndFreeMolalityAndMineralMoles()[basis_ind] *
144  mgd.basis_species_molecular_weight[basis_ind] * 1000.0;
145  break;
147  ret = egs.getSolventMassAndFreeMolalityAndMineralMoles()[basis_ind] *
149  break;
151  ret = -std::log10(egs.getBasisActivity(basis_ind));
152  break;
154  ret = egs.getBasisActivity(basis_ind);
155  break;
157  ret = egs.getBulkMolesOld()[basis_ind];
158  break;
159  default:
160  ret = egs.getSolventMassAndFreeMolalityAndMineralMoles()[basis_ind];
161  }
162  }
163  else if (mgd.eqm_species_index.count(_species) == 1)
164  {
165  const unsigned eqm_ind = mgd.eqm_species_index.at(_species);
166  switch (_quantity_choice)
167  {
169  ret = egs.getEquilibriumMolality(eqm_ind) * mgd.eqm_species_molecular_weight[eqm_ind] *
170  1000.0;
171  break;
173  ret = egs.getEquilibriumMolality(eqm_ind) * mgd.eqm_species_molecular_volume[eqm_ind];
174  break;
176  ret = egs.getEquilibriumMolality(eqm_ind) * mgd.eqm_species_molecular_weight[eqm_ind] *
177  1000.0;
178  break;
180  ret = -std::log10(egs.getEquilibriumActivity(eqm_ind));
181  break;
183  ret = egs.getEquilibriumActivity(eqm_ind);
184  break;
186  ret = 0.0;
187  break;
188  default:
189  ret = egs.getEquilibriumMolality(eqm_ind);
190  }
191  }
192  else
193  {
194  const unsigned kin_ind = mgd.kin_species_index.at(_species);
195  switch (_quantity_choice)
196  {
198  ret = egs.getKineticMoles(kin_ind) * mgd.kin_species_molecular_volume[kin_ind];
199  break;
201  ret = egs.getKineticMoles(kin_ind) * mgd.kin_species_molecular_weight[kin_ind] * 1000.0;
202  break;
204  ret = _reactor.getMoleAdditions(_current_node->id())(kin_ind + egs.getNumInBasis());
205  break;
206  default:
207  ret = egs.getKineticMoles(kin_ind);
208  }
209  }
210  }
211  return ret;
212 }
std::vector< Real > eqm_species_molecular_weight
all quantities have a molecular weight (g)
Real getTemperature() const
std::vector< bool > kin_species_mineral
kin_species_mineral[j] = true iff the j^th kinetic species is a mineral
AuxKernel to extract information from a Geochemistry*Reactor to record into an AuxVariable.
unsigned getIndexOfOriginalBasisSpecies(const std::string &name) const
std::vector< std::string > surface_sorption_name
surface_sorption_name[k] = name of the mineral involved in surface sorption.
GeochemistryQuantityAux(const InputParameters &parameters)
const std::vector< Real > & getBulkMolesOld() const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
registerMooseObject("GeochemistryApp", GeochemistryQuantityAux)
const std::string & _species
The species of interest.
std::unordered_map< std::string, unsigned > basis_species_index
basis_species_index[name] = index of the basis species, within all ModelGeochemicalDatabase internal ...
const Node *const & _current_node
const ModelGeochemicalDatabase mgd
std::vector< Real > kin_species_molecular_weight
all quantities have a molecular weight (g/mol)
std::vector< Real > kin_species_molecular_volume
all quantities have a molecular volume (cm^3/mol) (only nonzero for minerals, however) ...
const GeochemistryReactorBase & _reactor
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
void addRequiredParam(const std::string &name, const std::string &doc_string)
unsigned getNumInBasis() const
returns the number of species in the basis
std::unordered_map< std::string, unsigned > kin_species_index
kin_species_index[name] = index of the kinetic species, within all ModelGeochemicalDatabase internal ...
Real getBasisActivity(unsigned i) const
Real getEquilibriumActivity(unsigned eqm_ind) const
Returns the value of activity for the equilibrium species with index eqm_index.
const ModelGeochemicalDatabase & modelGeochemicalDatabase() const
Return a reference to the ModelGeochemicalDatabase structure.
virtual const GeochemicalSystem & getGeochemicalSystem(dof_id_type node_id) const =0
Real getKineticMoles(unsigned kin) const
virtual Real getMolesDumped(dof_id_type node_id, const std::string &species) const =0
Constructs and stores a minimal amount of information that is pertinent to the user-defined geochemic...
const ModelGeochemicalDatabase & getModelGeochemicalDatabase() const
virtual const DenseVector< Real > & getMoleAdditions(dof_id_type node_id) const =0
void paramError(const std::string &param, Args... args) const
unsigned _surface_sorption_mineral_index
index into mgd.surface_sorption_name corresponding to the species: this is used if quantity is surfac...
std::vector< Real > basis_species_molecular_weight
all quantities have a molecular weight (g)
enum GeochemistryQuantityAux::QuantityChoiceEnum _quantity_choice
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real getSurfacePotential(unsigned sp) const
std::vector< Real > eqm_species_molecular_volume
all quantities have a molecular volume (cm^3) (only nonzero for minerals, however) ...
Real getEquilibriumMolality(unsigned j) const
This class holds information about bulk composition, molalities, activities, activity coefficients...
virtual Real computeValue() override
std::vector< bool > basis_species_mineral
basis_species_mineral[j] = true iff the j^th basis species is a mineral
void addClassDescription(const std::string &doc_string)
Data structure to hold all relevant information from the database file.
static InputParameters validParams()
std::vector< bool > eqm_species_mineral
eqm_species_mineral[i] = true iff the i^th equilibrium species is a mineral
std::vector< Real > basis_species_molecular_volume
all quantities have a molecular volume (cm^3) (only nonzero for minerals, however) ...
const std::vector< Real > & getSolventMassAndFreeMolalityAndMineralMoles() const
DenseVector< Real > getTransportedBulkInOriginalBasis() const
Base class that controls the spatio-temporal solution of geochemistry reactions.
static InputParameters validParams()
void declareControllable(const std::string &name, std::set< ExecFlagType > execute_flags={})
Real getSurfaceCharge(unsigned sp) const
const PertinentGeochemicalSystem & getPertinentGeochemicalSystem() const
returns a reference to the PertinentGeochemicalSystem used to creat the ModelGeochemicalDatabase ...