- intrinsic_rate_constantThe intrinsic rate constant for the reaction
C++ Type:double
Description:The intrinsic rate constant for the reaction
 - kinetic_species_nameThe name of the kinetic species that will be controlled by this rate
C++ Type:std::string
Description:The name of the kinetic species that will be controlled by this rate
 
GeochemistryKineticRate
Defines a kinetic rate for a kinetic species. The general form of this rate is This is a rather complicated equation, and simple examples are given below. In this equation:
(units: mol.s) is the rate of the kinetic reaction. If it is positive then the kinetic species' mass will be decreasing (eg, dissolution). If it is negative then the kinetic species' mass will be increasing (eg, precipitation).
is the intrinsic rate constant. The product has units mol.s (assuming the simulation's time units are seconds). Note that mole units are used, even if the initial amount of the kinetic species is given in mass or volume units. Examples of are given below.
is either the surface area (units: m) for the kinetic species, or the specific surface area (units: m.g)
(units: g) is the mass of the kinetic species. It is optional. Examples are given below.
is a label denoting a promoting species
is either: mass of solvent water (in kg) if the promoting species is HO; fugacity of a gas if the promoting species is a gas; activity if the promoting species is either H or OH; mobility, otherwise.
is a dimensionless power
is the activity product defined by the kinetic species' reaction in the database file
is the reaction's equilibrium constant defined in the database file
and are dimensionless exponents
(units: J.mol) is the activation energy
J.K.mol is the gas constant
(units: K) is a reference temperature
(units: K) is the temperature
is -1 if (kinetic species mass will increase with time), 1 if (kinetic species mass will decrease with time).
Note that more than one GeochemistryKineticRate can be prescribed to a single kinetic species.  The sum of all the individual rates defines the overall rate for each species (see Example 6).  Simply supply your GeochemicalModelDefinition with a list of all the rates.
Example 1
Suppose that the kinetic rate is just a constant: for both the forward and backward reactions (ie, for precipitation and dissolution). Then set:
to the constant value, with units mol.s (assuming the simulation time is measured in seconds)
and
multiply_by_mass = falsedo not use any
promoting_species_namesorpromoting_species_indicesset and
set .
Example 2
Suppose that the kinetic rate for a certain mineral is proportional the mineral's surface area and that the surface area is known and fixed. Then set:
to the coefficient of proportionality, with units mol.m.s (assuming the simulation time is measured in seconds)
to the known mineral surface area, with units m
multiply_by_mass = falsedo not use any
promoting_species_namesorpromoting_species_indicesset and
set .
Example 3
Suppose that the kinetic rate for a certain mineral is proportional the mineral's free mass Then set
to the coefficient of proportionality, with units mol.g.s (assuming the simulation time is measured in seconds)
multiply_by_mass = true. MOOSE will automatically calculate the mineral's free mass depending on its molar mass and the number of free moles.do not use any
promoting_species_namesorpromoting_species_indicesset and
set .
Example 4
Suppose that the kinetic rate for a certain mineral is proportional the mineral surface area but that the surface area itself isn't known. Only the mineral's specific surface area (surface area per gram of free mineral m.g) is known. Then set
to the coefficient of proportionality, with units mol.m.s (assuming the simulation time is measured in seconds)
to be the mineral specific surface area, with units m.g.
multiply_by_mass = true. MOOSE will automatically calculate the mineral's free mass depending on its molar mass and the number of free moles.do not use any
promoting_species_namesorpromoting_species_indicesset and
set .
Example 5
Suppose that the kinetic rate for a certain redox couple is proportional the quantity of solvent water present: Then set
to the coefficient of proportionality, with units mol.kg.s (assuming the simulation time is measured in seconds)
and
multiply_by_mass = false.promoting_species_names = H2Oandpromoting_species_indices = 1set and
set .
Example 6
Suppose that the kinetic rate for a certain redox couple depends on the pH:  For this, two GeochemistryKineticRate UserObjects must be created.  Each has , multiply_by_mass = false, ,  and .
The first has ,
promoting_species_names = H+andpromoting_species_indices = 1.The second has ,
promoting_species_names = OH-andpromoting_species_indices = 1.5.
These are then supplied to the GeochemicalModelDefinition using its kinetic_rate_descriptions input.
Example 7
Suppose that the kinetic rate for a certain redox couple depends on the pH, the molality of Ca and the temperature: Then set
and
multiply_by_mass = falsepromoting_species_names = "H+ Ca++" and and promoting_species_indices = "1.5 0.3"
one_over_T0 = 0
Input Parameters
- activation_energy0Activation energy, in J.mol^-1, which appears in exp(activation_energy / R * (1/T0 - 1/T))
Default:0
C++ Type:double
Options:
Description:Activation energy, in J.mol^-1, which appears in exp(activation_energy / R * (1/T0 - 1/T))
 - area_quantity1The surface area of the kinetic species in m^2 (if multiply_by_mass = false) or the specific surface area of the kinetic species in m^2/g (if multiply_by_mass = true)
Default:1
C++ Type:double
Options:
Description:The surface area of the kinetic species in m^2 (if multiply_by_mass = false) or the specific surface area of the kinetic species in m^2/g (if multiply_by_mass = true)
 - eta1Eta parameter, which appears in |1 - (Q/K)^theta|^eta
Default:1
C++ Type:double
Options:
Description:Eta parameter, which appears in |1 - (Q/K)^theta|^eta
 - execute_onTIMESTEP_ENDThe list of flag(s) indicating when this object should be executed, the available options include NONE, INITIAL, LINEAR, NONLINEAR, TIMESTEP_END, TIMESTEP_BEGIN, FINAL, CUSTOM.
Default:TIMESTEP_END
C++ Type:ExecFlagEnum
Options:NONE, INITIAL, LINEAR, NONLINEAR, TIMESTEP_END, TIMESTEP_BEGIN, FINAL, CUSTOM
Description:The list of flag(s) indicating when this object should be executed, the available options include NONE, INITIAL, LINEAR, NONLINEAR, TIMESTEP_END, TIMESTEP_BEGIN, FINAL, CUSTOM.
 - multiply_by_massFalseWhether the rate should be multiplied by the kinetic species mass
Default:False
C++ Type:bool
Options:
Description:Whether the rate should be multiplied by the kinetic species mass
 - one_over_T001/T0, in 1/Kelvin, which appears in exp(activation_energy / R * (1/T0 - 1/T))
Default:0
C++ Type:double
Options:
Description:1/T0, in 1/Kelvin, which appears in exp(activation_energy / R * (1/T0 - 1/T))
 - promoting_species_indicesIndices of the promoting species
C++ Type:std::vector<double>
Options:
Description:Indices of the promoting species
 - promoting_species_namesNames of any promoting species
C++ Type:std::vector<std::string>
Options:
Description:Names of any promoting species
 - theta1Theta parameter, which appears in |1 - (Q/K)^theta|^eta
Default:1
C++ Type:double
Options:
Description:Theta parameter, which appears in |1 - (Q/K)^theta|^eta
 
Optional Parameters
- allow_duplicate_execution_on_initialFalseIn the case where this UserObject is depended upon by an initial condition, allow it to be executed twice during the initial setup (once before the IC and again after mesh adaptivity (if applicable).
Default:False
C++ Type:bool
Options:
Description:In the case where this UserObject is depended upon by an initial condition, allow it to be executed twice during the initial setup (once before the IC and again after mesh adaptivity (if applicable).
 - control_tagsAdds user-defined labels for accessing object parameters via control logic.
C++ Type:std::vector<std::string>
Options:
Description:Adds user-defined labels for accessing object parameters via control logic.
 - enableTrueSet the enabled status of the MooseObject.
Default:True
C++ Type:bool
Options:
Description:Set the enabled status of the MooseObject.
 - force_preauxFalseForces the GeneralUserObject to be executed in PREAUX
Default:False
C++ Type:bool
Options:
Description:Forces the GeneralUserObject to be executed in PREAUX
 - force_preicFalseForces the GeneralUserObject to be executed in PREIC during initial setup
Default:False
C++ Type:bool
Options:
Description:Forces the GeneralUserObject to be executed in PREIC during initial setup
 - use_displaced_meshFalseWhether or not this object should use the displaced mesh for computation. Note that in the case this is true but no displacements are provided in the Mesh block the undisplaced mesh will still be used.
Default:False
C++ Type:bool
Options:
Description:Whether or not this object should use the displaced mesh for computation. Note that in the case this is true but no displacements are provided in the Mesh block the undisplaced mesh will still be used.
 
Advanced Parameters
Input Files
- (modules/combined/examples/geochem-porous_flow/forge/aquifer_geochemistry.i)
 - (modules/combined/examples/geochem-porous_flow/forge/kinetic.i)
 - (modules/geochemistry/test/tests/kinetics/quartz_deposition.i)
 - (modules/geochemistry/test/tests/geochemistry_quantity_aux/kinetic_rate.i)
 - (modules/geochemistry/test/tests/time_dependent_reactions/flushing_case2.i)
 - (modules/geochemistry/test/tests/time_dependent_reactions/flushing_case1.i)
 - (modules/geochemistry/test/tests/time_dependent_reactions/flushing_case3.i)
 - (modules/geochemistry/test/tests/time_dependent_reactions/flushing.i)
 - (modules/combined/examples/geochem-porous_flow/forge/reservoir_and_water_3.i)
 - (modules/geochemistry/test/tests/kinetics/quartz_dissolution.i)
 - (modules/combined/examples/geochem-porous_flow/geotes_2D/aquifer_geochemistry.i)
 - (modules/combined/examples/geochem-porous_flow/forge/natural_reservoir.i)
 - (modules/geochemistry/test/tests/kinetics/kinetic_albite.i)
 - (modules/combined/examples/geochem-porous_flow/geotes_2D/aquifer_un_quartz_geochemistry.i)
 
(modules/combined/examples/geochem-porous_flow/forge/aquifer_geochemistry.i)
# Simulates geochemistry in the aquifer.  This input file may be run in standalone fashion, which will study the natural kinetically-controlled mineral changes in the same way as natural_reservoir.i.  To simulate the FORGE injection scenario, run the porous_flow.i simulation which couples to this input file using MultiApps.
# This file receives pf_rate_H pf_rate_Na pf_rate_K pf_rate_Ca pf_rate_Mg pf_rate_SiO2 pf_rate_Al pf_rate_Cl pf_rate_SO4 pf_rate_HCO3 pf_rate_H2O and temperature as AuxVariables from porous_flow.i
# The pf_rate quantities are kg/s changes of fluid-component mass at each node, but the geochemistry module expects rates-of-changes of moles at every node.  Secondly, since this input file considers just 1 litre of aqueous solution at every node, the nodal_void_volume is used to convert pf_rate_* into rate_*_per_1l, which is measured in mol/s/1_litre_of_aqueous_solution.
# This file sends massfrac_H massfrac_Na massfrac_K massfrac_Ca massfrac_Mg massfrac_SiO2 massfrac_Al massfrac_Cl massfrac_SO4 massfrac_HCO3 to porous_flow.i.  These are computed from the corresponding transported_* quantities.
# The results depend on the kinetic rates used and these are recognised to be poorly constrained by experiment
[UserObjects]
  [rate_Albite]
    type = GeochemistryKineticRate
    kinetic_species_name = Albite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 69.8E3
    one_over_T0 = 0.003354
  []
  [rate_Anhydrite]
    type = GeochemistryKineticRate
    kinetic_species_name = Anhydrite
    intrinsic_rate_constant = 1.0E-7
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 14.3E3
    one_over_T0 = 0.003354
  []
  [rate_Anorthite]
    type = GeochemistryKineticRate
    kinetic_species_name = Anorthite
    intrinsic_rate_constant = 1.0E-13
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 17.8E3
    one_over_T0 = 0.003354
  []
  [rate_Calcite]
    type = GeochemistryKineticRate
    kinetic_species_name = Calcite
    intrinsic_rate_constant = 1.0E-10
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 23.5E3
    one_over_T0 = 0.003354
  []
  [rate_Chalcedony]
    type = GeochemistryKineticRate
    kinetic_species_name = Chalcedony
    intrinsic_rate_constant = 1.0E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 90.1E3
    one_over_T0 = 0.003354
  []
  [rate_Clinochl-7A]
    type = GeochemistryKineticRate
    kinetic_species_name = Clinochl-7A
    intrinsic_rate_constant = 1.0E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 88.0E3
    one_over_T0 = 0.003354
  []
  [rate_Illite]
    type = GeochemistryKineticRate
    kinetic_species_name = Illite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 29E3
    one_over_T0 = 0.003354
  []
  [rate_K-feldspar]
    type = GeochemistryKineticRate
    kinetic_species_name = K-feldspar
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 38E3
    one_over_T0 = 0.003354
  []
  [rate_Kaolinite]
    type = GeochemistryKineticRate
    kinetic_species_name = Kaolinite
    intrinsic_rate_constant = 1E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22.2E3
    one_over_T0 = 0.003354
  []
  [rate_Quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 90.1E3
    one_over_T0 = 0.003354
  []
  [rate_Paragonite]
    type = GeochemistryKineticRate
    kinetic_species_name = Paragonite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22E3
    one_over_T0 = 0.003354
  []
  [rate_Phlogopite]
    type = GeochemistryKineticRate
    kinetic_species_name = Phlogopite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22E3
    one_over_T0 = 0.003354
  []
  [rate_Laumontite]
    type = GeochemistryKineticRate
    kinetic_species_name = Laumontite
    intrinsic_rate_constant = 1.0E-15
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 17.8E3
    one_over_T0 = 0.003354
  []
  [rate_Zoisite]
    type = GeochemistryKineticRate
    kinetic_species_name = Zoisite
    intrinsic_rate_constant = 1E-16
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 66.1E3
    one_over_T0 = 0.003354
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = '../../../../geochemistry/database/moose_geochemdb.json'
    basis_species = 'H2O H+ Na+ K+ Ca++ Mg++ SiO2(aq) Al+++ Cl- SO4-- HCO3-'
    remove_all_extrapolated_secondary_species = true
    kinetic_minerals = 'Albite Anhydrite Anorthite Calcite Chalcedony Clinochl-7A Illite K-feldspar Kaolinite Quartz Paragonite Phlogopite Zoisite Laumontite'
    kinetic_rate_descriptions = 'rate_Albite rate_Anhydrite rate_Anorthite rate_Calcite rate_Chalcedony rate_Clinochl-7A rate_Illite rate_K-feldspar rate_Kaolinite rate_Quartz rate_Paragonite rate_Phlogopite rate_Zoisite rate_Laumontite'
  []
  [nodal_void_volume_uo]
    type = NodalVoidVolume
    porosity = porosity
    execute_on = 'initial timestep_end' # "initial" means this is evaluated properly for the first timestep
  []
[]
[SpatialReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = 'Cl-'
  constraint_species = 'H2O              H+                  Na+              K+                 Ca++              Mg++                SiO2(aq)           Al+++               Cl-                SO4--               HCO3-'
# Following numbers are from water_60_to_220degC_out.csv
  constraint_value = '  1.0006383866109  9.5165072498215e-07 0.100020379171   0.0059389061065    0.011570884507621 4.6626763057447e-06 0.0045110404925255 5.8096968688789e-17 0.13500708594394   6.6523540147676e-05 7.7361407898089e-05'
  constraint_meaning = 'kg_solvent_water free_concentration       free_concentration    free_concentration      free_concentration     free_concentration       free_concentration      free_concentration       bulk_composition free_concentration       free_concentration'
  constraint_unit = '   kg               molal               molal            molal              molal             molal               molal              molal               moles              molal               molal'
  initial_temperature = 220
  temperature = temperature
  kinetic_species_name = '         Albite             Anorthite          K-feldspar         Quartz             Phlogopite         Paragonite         Calcite            Anhydrite          Chalcedony         Illite             Kaolinite          Clinochl-7A        Zoisite            Laumontite'
  kinetic_species_initial_value = '4.324073236492E+02 4.631370307325E+01 2.685015418378E+02 7.720095013956E+02 1.235192062541E+01 7.545461404965E-01 4.234651808835E-04 4.000485907930E-04 4.407616361072E+00 1.342524904876E+01 1.004823151125E+00 4.728132387707E-01 7.326007326007E-01 4.818116116598E-01'
  kinetic_species_unit = '         moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles'
  evaluate_kinetic_rates_always = true # otherwise will easily "run out" of dissolving species
  source_species_names = 'H2O H+ Na+ K+ Ca++ Mg++ SiO2(aq) Al+++ Cl- SO4-- HCO3-'
  source_species_rates = 'rate_H2O_per_1l rate_H_per_1l rate_Na_per_1l rate_K_per_1l rate_Ca_per_1l rate_Mg_per_1l rate_SiO2_per_1l rate_Al_per_1l rate_Cl_per_1l rate_SO4_per_1l rate_HCO3_per_1l'
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  execute_console_output_on = ''
  add_aux_molal = false # save some memory and reduce variables in output exodus
  add_aux_mg_per_kg = false # save some memory and reduce variables in output exodus
  add_aux_free_mg = false # save some memory and reduce variables in output exodus
  add_aux_activity = false # save some memory and reduce variables in output exodus
  add_aux_bulk_moles = false # save some memory and reduce variables in output exodus
  adaptive_timestepping = true
[]
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    nx = 15
    ny = 10
    xmin = -100
    xmax = 200
    ymin = -100
    ymax = 100
  []
  [injection_node]
    input = gen
    type = ExtraNodesetGenerator
    new_boundary = injection_node
    coord = '0 0 0'
  []
[]
[Executioner]
  type = Transient
  [TimeStepper]
    type = FunctionDT
    function = 'max(1E6, 0.3 * t)'
  []
  end_time = 4E12
[]
[AuxVariables]
  [temperature]
    initial_condition = 220.0
  []
  [porosity]
    initial_condition = 0.01
  []
  [nodal_void_volume]
  []
  [free_cm3_Kfeldspar] # necessary because of the minus sign in K-feldspar which does not parse correctly in the porosity AuxKernel
  []
  [free_cm3_Clinochl7A] # necessary because of the minus sign in Clinochl-7A which does not parse correctly in the porosity AuxKernel
  []
  [pf_rate_H] # change in H mass (kg/s) at each node provided by the porous-flow simulation
  []
  [pf_rate_Na]
  []
  [pf_rate_K]
  []
  [pf_rate_Ca]
  []
  [pf_rate_Mg]
  []
  [pf_rate_SiO2]
  []
  [pf_rate_Al]
  []
  [pf_rate_Cl]
  []
  [pf_rate_SO4]
  []
  [pf_rate_HCO3]
  []
  [pf_rate_H2O] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [rate_H_per_1l]
  []
  [rate_Na_per_1l]
  []
  [rate_K_per_1l]
  []
  [rate_Ca_per_1l]
  []
  [rate_Mg_per_1l]
  []
  [rate_SiO2_per_1l]
  []
  [rate_Al_per_1l]
  []
  [rate_Cl_per_1l]
  []
  [rate_SO4_per_1l]
  []
  [rate_HCO3_per_1l]
  []
  [rate_H2O_per_1l]
  []
  [transported_H]
  []
  [transported_Na]
  []
  [transported_K]
  []
  [transported_Ca]
  []
  [transported_Mg]
  []
  [transported_SiO2]
  []
  [transported_Al]
  []
  [transported_Cl]
  []
  [transported_SO4]
  []
  [transported_HCO3]
  []
  [transported_H2O]
  []
  [transported_mass]
  []
  [massfrac_H]
  []
  [massfrac_Na]
  []
  [massfrac_K]
  []
  [massfrac_Ca]
  []
  [massfrac_Mg]
  []
  [massfrac_SiO2]
  []
  [massfrac_Al]
  []
  [massfrac_Cl]
  []
  [massfrac_SO4]
  []
  [massfrac_HCO3]
  []
  [massfrac_H2O]
  []
[]
[AuxKernels]
  [free_cm3_Kfeldspar]
    type = GeochemistryQuantityAux
    variable = free_cm3_Kfeldspar
    species = 'K-feldspar'
    quantity = free_cm3
    execute_on = 'timestep_begin timestep_end'
  []
  [free_cm3_Clinochl7A]
    type = GeochemistryQuantityAux
    variable = free_cm3_Clinochl7A
    species = 'Clinochl-7A'
    quantity = free_cm3
    execute_on = 'timestep_begin timestep_end'
  []
  [porosity_auxk]
    type = ParsedAux
    args = 'free_cm3_Albite free_cm3_Anhydrite free_cm3_Anorthite free_cm3_Calcite free_cm3_Chalcedony free_cm3_Clinochl7A free_cm3_Illite free_cm3_Kfeldspar free_cm3_Kaolinite free_cm3_Quartz free_cm3_Paragonite free_cm3_Phlogopite free_cm3_Zoisite free_cm3_Laumontite'
    function = '1000.0 / (1000.0 + free_cm3_Albite + free_cm3_Anhydrite + free_cm3_Anorthite + free_cm3_Calcite + free_cm3_Chalcedony + free_cm3_Clinochl7A + free_cm3_Illite + free_cm3_Kfeldspar + free_cm3_Kaolinite + free_cm3_Quartz + free_cm3_Paragonite + free_cm3_Phlogopite + free_cm3_Zoisite + free_cm3_Laumontite)'
    variable = porosity
    execute_on = 'timestep_end'
  []
  [nodal_void_volume_auxk]
    type = NodalVoidVolumeAux
    variable = nodal_void_volume
    nodal_void_volume_uo = nodal_void_volume_uo
    execute_on = 'initial timestep_end' # "initial" to ensure it is properly evaluated for the first timestep
  []
  [rate_H_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_H nodal_void_volume'
    variable = rate_H_per_1l
    function = 'pf_rate_H / 1.0079 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Na_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_Na nodal_void_volume'
    variable = rate_Na_per_1l
    function = 'pf_rate_Na / 22.9898 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_K_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_K nodal_void_volume'
    variable = rate_K_per_1l
    function = 'pf_rate_K / 39.0983 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Ca_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_Ca nodal_void_volume'
    variable = rate_Ca_per_1l
    function = 'pf_rate_Ca / 40.08 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Mg_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_Mg nodal_void_volume'
    variable = rate_Mg_per_1l
    function = 'pf_rate_Mg / 24.305 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_SiO2_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_SiO2 nodal_void_volume'
    variable = rate_SiO2_per_1l
    function = 'pf_rate_SiO2 / 60.0843 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Al_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_Al nodal_void_volume'
    variable = rate_Al_per_1l
    function = 'pf_rate_Al / 26.9815 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Cl_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_Cl nodal_void_volume'
    variable = rate_Cl_per_1l
    function = 'pf_rate_Cl / 35.453 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_SO4_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_SO4 nodal_void_volume'
    variable = rate_SO4_per_1l
    function = 'pf_rate_SO4 / 96.0576 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_HCO3_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_HCO3 nodal_void_volume'
    variable = rate_HCO3_per_1l
    function = 'pf_rate_HCO3 / 61.0171 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_H2O_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_H2O nodal_void_volume'
    variable = rate_H2O_per_1l
    function = 'pf_rate_H2O / 18.01801802 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [transported_H_auxk]
    type = GeochemistryQuantityAux
    variable = transported_H
    species = 'H+'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_Na_auxk]
    type = GeochemistryQuantityAux
    variable = transported_Na
    species = 'Na+'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_K_auxk]
    type = GeochemistryQuantityAux
    variable = transported_K
    species = 'K+'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_Ca_auxk]
    type = GeochemistryQuantityAux
    variable = transported_Ca
    species = 'Ca++'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_Mg_auxk]
    type = GeochemistryQuantityAux
    variable = transported_Mg
    species = 'Mg++'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_SiO2_auxk]
    type = GeochemistryQuantityAux
    variable = transported_SiO2
    species = 'SiO2(aq)'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_Al_auxk]
    type = GeochemistryQuantityAux
    variable = transported_Al
    species = 'Al+++'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_Cl_auxk]
    type = GeochemistryQuantityAux
    variable = transported_Cl
    species = 'Cl-'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_SO4_auxk]
    type = GeochemistryQuantityAux
    variable = transported_SO4
    species = 'SO4--'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_HCO3_auxk]
    type = GeochemistryQuantityAux
    variable = transported_HCO3
    species = 'HCO3-'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_H2O_auxk]
    type = GeochemistryQuantityAux
    variable = transported_H2O
    species = 'H2O'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_begin'
  []
  [transported_mass_auxk]
    type = ParsedAux
    args = ' transported_H transported_Na transported_K transported_Ca transported_Mg transported_SiO2 transported_Al transported_Cl transported_SO4 transported_HCO3 transported_H2O'
    variable = transported_mass
    function = 'transported_H * 1.0079 + transported_Cl * 35.453 + transported_SO4 * 96.0576 + transported_HCO3 * 61.0171 + transported_SiO2 * 60.0843 + transported_Al * 26.9815 + transported_Ca * 40.08 + transported_Mg * 24.305 + transported_K * 39.0983 + transported_Na * 22.9898 + transported_H2O * 18.01801802'
    execute_on = 'timestep_end'
  []
  [massfrac_H_auxk]
    type = ParsedAux
    args = 'transported_H transported_mass'
    variable = massfrac_H
    function = 'transported_H * 1.0079 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Na_auxk]
    type = ParsedAux
    args = 'transported_Na transported_mass'
    variable = massfrac_Na
    function = 'transported_Na * 22.9898 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_K_auxk]
    type = ParsedAux
    args = 'transported_K transported_mass'
    variable = massfrac_K
    function = 'transported_K * 39.0983 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Ca_auxk]
    type = ParsedAux
    args = 'transported_Ca transported_mass'
    variable = massfrac_Ca
    function = 'transported_Ca * 40.08 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Mg_auxk]
    type = ParsedAux
    args = 'transported_Mg transported_mass'
    variable = massfrac_Mg
    function = 'transported_Mg * 24.305 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_SiO2_auxk]
    type = ParsedAux
    args = 'transported_SiO2 transported_mass'
    variable = massfrac_SiO2
    function = 'transported_SiO2 * 60.0843 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Al_auxk]
    type = ParsedAux
    args = 'transported_Al transported_mass'
    variable = massfrac_Al
    function = 'transported_Al * 26.9815 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Cl_auxk]
    type = ParsedAux
    args = 'transported_Cl transported_mass'
    variable = massfrac_Cl
    function = 'transported_Cl * 35.453 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_SO4_auxk]
    type = ParsedAux
    args = 'transported_SO4 transported_mass'
    variable = massfrac_SO4
    function = 'transported_SO4 * 96.0576 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_HCO3_auxk]
    type = ParsedAux
    args = 'transported_HCO3 transported_mass'
    variable = massfrac_HCO3
    function = 'transported_HCO3 * 61.0171 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_H2O_auxk]
    type = ParsedAux
    args = 'transported_H2O transported_mass'
    variable = massfrac_H2O
    function = 'transported_H2O * 18.01801802 / transported_mass'
    execute_on = 'timestep_end'
  []
[]
[GlobalParams]
  point = '0 0 0'
  reactor = reactor
[]
[Postprocessors]
  [temperature]
    type = PointValue
    variable = 'solution_temperature'
  []
  [porosity]
    type = PointValue
    variable = porosity
  []
  [solution_temperature]
    type = PointValue
    variable = solution_temperature
  []
  [massfrac_H]
    type = PointValue
    variable = massfrac_H
  []
  [massfrac_Na]
    type = PointValue
    variable = massfrac_Na
  []
  [massfrac_K]
    type = PointValue
    variable = massfrac_K
  []
  [massfrac_Ca]
    type = PointValue
    variable = massfrac_Ca
  []
  [massfrac_Mg]
    type = PointValue
    variable = massfrac_Mg
  []
  [massfrac_SiO2]
    type = PointValue
    variable = massfrac_SiO2
  []
  [massfrac_Al]
    type = PointValue
    variable = massfrac_Al
  []
  [massfrac_Cl]
    type = PointValue
    variable = massfrac_Cl
  []
  [massfrac_SO4]
    type = PointValue
    variable = massfrac_SO4
  []
  [massfrac_HCO3]
    type = PointValue
    variable = massfrac_HCO3
  []
  [massfrac_H2O]
    type = PointValue
    variable = massfrac_H2O
  []
  [cm3_Albite]
    type = PointValue
    variable = 'free_cm3_Albite'
  []
  [cm3_Anhydrite]
    type = PointValue
    variable = 'free_cm3_Anhydrite'
  []
  [cm3_Anorthite]
    type = PointValue
    variable = 'free_cm3_Anorthite'
  []
  [cm3_Calcite]
    type = PointValue
    variable = 'free_cm3_Calcite'
  []
  [cm3_Chalcedony]
    type = PointValue
    variable = 'free_cm3_Chalcedony'
  []
  [cm3_Clinochl-7A]
    type = PointValue
    variable = 'free_cm3_Clinochl-7A'
  []
  [cm3_Illite]
    type = PointValue
    variable = 'free_cm3_Illite'
  []
  [cm3_K-feldspar]
    type = PointValue
    variable = 'free_cm3_K-feldspar'
  []
  [cm3_Kaolinite]
    type = PointValue
    variable = 'free_cm3_Kaolinite'
  []
  [cm3_Quartz]
    type = PointValue
    variable = 'free_cm3_Quartz'
  []
  [cm3_Paragonite]
    type = PointValue
    variable = 'free_cm3_Paragonite'
  []
  [cm3_Phlogopite]
    type = PointValue
    variable = 'free_cm3_Phlogopite'
  []
  [cm3_Zoisite]
    type = PointValue
    variable = 'free_cm3_Zoisite'
  []
  [cm3_Laumontite]
    type = PointValue
    variable = 'free_cm3_Laumontite'
  []
  [cm3_mineral]
    type = LinearCombinationPostprocessor
    pp_names = 'cm3_Albite cm3_Anhydrite cm3_Anorthite cm3_Calcite cm3_Chalcedony cm3_Clinochl-7A cm3_Illite cm3_K-feldspar cm3_Kaolinite cm3_Quartz cm3_Paragonite cm3_Phlogopite cm3_Zoisite cm3_Laumontite'
    pp_coefs = '1 1 1 1 1 1 1 1 1 1 1 1 1 1'
  []
  [pH]
    type = PointValue
    variable = 'pH'
  []
[]
[Outputs]
  [exo]
    type = Exodus
    execute_on = final
  []
  csv = true
[]
(modules/combined/examples/geochem-porous_flow/forge/kinetic.i)
# Simulation to check that the output of water_60_to_220degC is indeed at equilibrium with the mineral assemblage.
# The initial mole numbers of the kinetic species are unimportant for this simulation, but are chosen to be consistent with other input files.  The numerical values are such that:
# - the mass fractions are: Albite 0.44; Anorthite 0.05; K-feldspar 0.29; Quartz 0.18, Phlgoptite 0.04 with trace amounts of Calcite and Anhydrite.  These are similar to that measured in bulk X-ray diffraction results of 10 samples from well 58-32, assuming that "plagioclase feldspar" consists of Albite and Anorthite in the ratio 9:1, and that Biotite is Phlogoptite, and the 2% Illite is added to Phlogoptite.  Precisely:
# - it is assumed that water_60_to_220degC consists of 1 litre of water (there is 1kg of solvent water) and that the porosity is 0.01, so the amount of rock should be 99000cm^3
# - the cm^3 of the trace minerals Calcite and Anhydrite is exactly given by water_60_to_220degC (0.016 and 0.018 respectively)
# - the total mineral volume is 99000cm^3, so that the porosity is 0.01
# - see initial_kinetic_moles.xlsx for the remaining mole numbers
[UserObjects]
  [rate_Albite]
    type = GeochemistryKineticRate
    kinetic_species_name = Albite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 69.8E3
    one_over_T0 = 0.003354
  []
  [rate_Anhydrite]
    type = GeochemistryKineticRate
    kinetic_species_name = Anhydrite
    intrinsic_rate_constant = 1.0E-7
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 14.3E3
    one_over_T0 = 0.003354
  []
  [rate_Anorthite]
    type = GeochemistryKineticRate
    kinetic_species_name = Anorthite
    intrinsic_rate_constant = 1.0E-13
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 17.8E3
    one_over_T0 = 0.003354
  []
  [rate_Calcite]
    type = GeochemistryKineticRate
    kinetic_species_name = Calcite
    intrinsic_rate_constant = 1.0E-10
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 23.5E3
    one_over_T0 = 0.003354
  []
  [rate_Chalcedony]
    type = GeochemistryKineticRate
    kinetic_species_name = Chalcedony
    intrinsic_rate_constant = 1.0E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 90.1E3
    one_over_T0 = 0.003354
  []
  [rate_Clinochl-7A]
    type = GeochemistryKineticRate
    kinetic_species_name = Clinochl-7A
    intrinsic_rate_constant = 1.0E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 88.0E3
    one_over_T0 = 0.003354
  []
  [rate_Illite]
    type = GeochemistryKineticRate
    kinetic_species_name = Illite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 29E3
    one_over_T0 = 0.003354
  []
  [rate_K-feldspar]
    type = GeochemistryKineticRate
    kinetic_species_name = K-feldspar
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 38E3
    one_over_T0 = 0.003354
  []
  [rate_Kaolinite]
    type = GeochemistryKineticRate
    kinetic_species_name = Kaolinite
    intrinsic_rate_constant = 1E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22.2E3
    one_over_T0 = 0.003354
  []
  [rate_Quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 90.1E3
    one_over_T0 = 0.003354
  []
  [rate_Paragonite]
    type = GeochemistryKineticRate
    kinetic_species_name = Paragonite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22E3
    one_over_T0 = 0.003354
  []
  [rate_Phlogopite]
    type = GeochemistryKineticRate
    kinetic_species_name = Phlogopite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22E3
    one_over_T0 = 0.003354
  []
  [rate_Zoisite]
    type = GeochemistryKineticRate
    kinetic_species_name = Zoisite
    intrinsic_rate_constant = 1E-16
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 66.1E3
    one_over_T0 = 0.003354
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = '../../../../geochemistry/database/moose_geochemdb.json'
    basis_species = 'H2O H+ Na+ K+ Ca++ Mg++ SiO2(aq) Al+++ Cl- SO4-- HCO3-'
    remove_all_extrapolated_secondary_species = true
    kinetic_minerals = 'Albite Anhydrite Anorthite Calcite Chalcedony Clinochl-7A Illite K-feldspar Kaolinite Quartz Paragonite Phlogopite'
    kinetic_rate_descriptions = 'rate_Albite rate_Anhydrite rate_Anorthite rate_Calcite rate_Chalcedony rate_Clinochl-7A rate_Illite rate_K-feldspar rate_Kaolinite rate_Quartz rate_Paragonite rate_Phlogopite'
  []
[]
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = 'Cl-'
  constraint_species = 'H2O              H+                  Na+              K+                 Ca++              Mg++                SiO2(aq)           Al+++               Cl-                SO4--               HCO3-'
# Following numbers are from water_60_to_220degC_out.csv
  constraint_value = '  1.0006383866109  9.5165072498215e-07 0.100020379171   0.0059389061065    0.011570884507621 4.6626763057447e-06 0.0045110404925255 5.8096968688789e-17 0.13500708594394   6.6523540147676e-05 7.7361407898089e-05'
  constraint_meaning = 'kg_solvent_water free_concentration       free_concentration    free_concentration     free_concentration   free_concentration       free_concentration      free_concentration       bulk_composition free_concentration       free_concentration'
  constraint_unit = '   kg               molal               molal            molal              molal           molal              molal              molal               moles              molal               molal'
  initial_temperature = 220
  temperature = 220
  kinetic_species_name = '         Albite           Anorthite       K-feldspar      Quartz           Phlogopite         Paragonite Calcite     Anhydrite   Chalcedony Illite Kaolinite Clinochl-7A'
  kinetic_species_initial_value = '4.3511787009E+02 4.660402064E+01 2.701846444E+02 7.7684884497E+02 2.4858697344E+01   1E-10      0.000423465 0.000400049 1E-10 1E-10 1E-10 1E-10'
  kinetic_species_unit = '         moles            moles           moles           moles            moles              moles      moles       moles       moles      moles  moles     moles'
  evaluate_kinetic_rates_always = true # otherwise will easily "run out" of dissolving species
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  mol_cutoff = 0.1
  execute_console_output_on = ''
[]
[Executioner]
  type = Transient
  [TimeStepper]
    type = FunctionDT
    function = '1E8'
  []
  end_time = 4E8
[]
[GlobalParams]
  point = '0 0 0'
[]
[Postprocessors]
  [cm3_Albite]
    type = PointValue
    variable = 'free_cm3_Albite'
  []
  [cm3_Anhydrite]
    type = PointValue
    variable = 'free_cm3_Anhydrite'
  []
  [cm3_Anorthite]
    type = PointValue
    variable = 'free_cm3_Anorthite'
  []
  [cm3_Calcite]
    type = PointValue
    variable = 'free_cm3_Calcite'
  []
  [cm3_Chalcedony]
    type = PointValue
    variable = 'free_cm3_Chalcedony'
  []
  [cm3_Clinochl-7A]
    type = PointValue
    variable = 'free_cm3_Clinochl-7A'
  []
  [cm3_Illite]
    type = PointValue
    variable = 'free_cm3_Illite'
  []
  [cm3_K-feldspar]
    type = PointValue
    variable = 'free_cm3_K-feldspar'
  []
  [cm3_Kaolinite]
    type = PointValue
    variable = 'free_cm3_Kaolinite'
  []
  [cm3_Quartz]
    type = PointValue
    variable = 'free_cm3_Quartz'
  []
  [cm3_Paragonite]
    type = PointValue
    variable = 'free_cm3_Paragonite'
  []
  [cm3_Phlogopite]
    type = PointValue
    variable = 'free_cm3_Phlogopite'
  []
  [cm3_mineral]
    type = LinearCombinationPostprocessor
    pp_names = 'cm3_Albite cm3_Anhydrite cm3_Anorthite cm3_Calcite cm3_Chalcedony cm3_Clinochl-7A cm3_Illite cm3_K-feldspar cm3_Kaolinite cm3_Quartz cm3_Paragonite cm3_Phlogopite'
    pp_coefs = '1 1 1 1 1 1 1 1 1 1 1 1'
  []
[]
[Outputs]
  csv = true
[]
(modules/geochemistry/test/tests/kinetics/quartz_deposition.i)
# Example of quartz deposition in a fracture, as the temperature is reduced from 300degC to 25degC
# The initial free molality of SiO2(aq) is determined using quartz_equilibrium_at300degC
[GlobalParams]
  point = '0 0 0'
[]
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  constraint_species = "H2O              Na+              Cl-              SiO2(aq)"
  constraint_value = "  1.0              1E-10            1E-10            0.009722905"
  constraint_meaning = "kg_solvent_water bulk_composition bulk_composition free_concentration"
  constraint_unit = "   kg               moles            moles            molal"
  initial_temperature = 300.0
  temperature = temp_controller
  kinetic_species_name = Quartz
  kinetic_species_initial_value = 400
  kinetic_species_unit = g
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  add_aux_pH = false # there is no H+ in this system
  evaluate_kinetic_rates_always = true # implicit time-marching used for stability
  execute_console_output_on = '' # only CSV output used in this example
[]
[UserObjects]
  [rate_quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 7.4112E2 # 2.35E-5mol/s/cm^2 = 7.411E2mol/yr/cm^2
    multiply_by_mass = true
    area_quantity = 1
    activation_energy = 72800.0
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "../../../database/moose_geochemdb.json"
    basis_species = "H2O SiO2(aq) Na+ Cl-"
    kinetic_minerals = "Quartz"
    kinetic_rate_descriptions = "rate_quartz"
  []
[]
[Executioner]
  type = Transient
  dt = 0.02
  end_time = 1 # measured in years
[]
[AuxVariables]
  [temp_controller]
  []
  [diss_rate]
  []
[]
[AuxKernels]
  [temp_controller_auxk]
    type = FunctionAux
    function = '300 - 275 * t'
    variable = temp_controller
    execute_on = 'timestep_begin'
  []
  [diss_rate]
    type = ParsedAux
    args = mol_change_Quartz
    function = '-mol_change_Quartz / 0.02' # 0.02 = timestep size
    variable = diss_rate
  []
[]
[Postprocessors]
  [mg_per_kg_sio2]
    type = PointValue
    variable = "mg_per_kg_SiO2(aq)"
  []
  [rate_mole_per_year]
    type = PointValue
    variable = diss_rate
  []
  [temperature]
    type = PointValue
    variable = "solution_temperature"
  []
[]
[Outputs]
  csv = true
[]
(modules/geochemistry/test/tests/geochemistry_quantity_aux/kinetic_rate.i)
#Extract -(kinetic rate times dt)
[TimeDependentReactionSolver]
  model_definition = definition
  charge_balance_species = "Cl-"
  constraint_species = "H2O H+ Cl- Fe+++ >(s)FeOH >(w)FeOH"
  constraint_value = "  1.0 4.0 1.0 0.1 1.0E-6 1.0E-6"
  constraint_meaning = "kg_solvent_water bulk_composition bulk_composition free_concentration free_concentration free_concentration"
  constraint_unit = "kg moles moles molal molal molal"
  kinetic_species_name = "Fe(OH)3(ppd)"
  kinetic_species_initial_value = "1.0"
  kinetic_species_unit = "moles"
  max_ionic_strength = 0.0
  ramp_max_ionic_strength_initial = 0
[]
[UserObjects]
  [constant_rate]
    type = GeochemistryKineticRate
    kinetic_species_name = "Fe(OH)3(ppd)"
    intrinsic_rate_constant = 1E-3
    eta = 0.0
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "../../database/ferric_hydroxide_sorption.json"
    basis_species = "H2O H+ Cl- Fe+++ >(s)FeOH >(w)FeOH"
    kinetic_minerals = "Fe(OH)3(ppd)"
    kinetic_rate_descriptions = "constant_rate"
  []
[]
[Executioner]
  type = Transient
  dt = 2
  end_time = 2
[]
[AuxVariables]
  [the_aux]
  []
[]
[AuxKernels]
  [the_aux]
    type = GeochemistryQuantityAux
    species = "Fe(OH)3(ppd)"
    reactor = geochemistry_reactor
    variable = the_aux
    quantity = kinetic_additions
  []
[]
[Postprocessors]
  [value]
    type = PointValue
    point = '0 0 0'
    variable = the_aux
  []
  [value_from_action]
    type = PointValue
    point = '0 0 0'
    variable = "mol_change_Fe(OH)3(ppd)"
  []
[]
[Outputs]
  csv = true
[]
(modules/geochemistry/test/tests/time_dependent_reactions/flushing_case2.i)
# Alkali flushing of a reservoir (an example of flushing): adding Na2CO3
# To determine the initial constraint_values, run flushing_equilibrium_at70degC.i
# Note that flushing_equilibrium_at70degC.i will have to be re-run when temperature-dependence has been added to geochemistry
# Note that Dawsonite is currently not included as an equilibrium_mineral, otherwise it is supersaturated in the initial configuration, so precipitates.  Bethke does not report this in Fig30.4, so I assume it is due to temperature dependence
[GlobalParams]
  point = '0 0 0'
[]
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  swap_into_basis = "Calcite Dolomite-ord Muscovite Kaolinite"
  swap_out_of_basis = "HCO3- Mg++ K+ Al+++"
  constraint_species = "H2O H+   Cl-       Na+       Ca++       Calcite   Dolomite-ord Muscovite Kaolinite SiO2(aq)"
  constraint_value = "  1.0 1E-5 2.1716946 1.0288941 0.21650572 10.177537 3.6826177    1.320907  1.1432682 6.318e-05"
  constraint_meaning = "kg_solvent_water activity bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition free_concentration"
  constraint_unit = "   kg              dimensionless moles          moles              moles              moles              moles              moles              moles              molal"
  initial_temperature = 70.0
  temperature = 70.0
  kinetic_species_name = Quartz
  kinetic_species_initial_value = 226.992243
  kinetic_species_unit = moles
  evaluate_kinetic_rates_always = true # implicit time-marching used for stability
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  close_system_at_time = 0.0
  remove_fixed_activity_name = "H+"
  remove_fixed_activity_time = 0.0
  mode = 3 # flush through the NaOH solution specified below:
  source_species_names = "H2O    Na+  CO3--"
  source_species_rates = "27.755 0.25 0.125" # 1kg water/2days = 27.755moles/day.  0.5mol Na+/2days = 0.25mol/day
[]
[UserObjects]
  [rate_quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1.3824E-13 # 1.6E-19mol/s/cm^2 = 1.3824E-13mol/day/cm^2
    multiply_by_mass = true
    area_quantity = 1000
    promoting_species_names = "H+"
    promoting_species_indices = "-0.5"
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "../../../database/moose_geochemdb.json"
    basis_species = "H2O H+ Cl- Na+ Ca++ HCO3- Mg++ K+ Al+++ SiO2(aq)"
    equilibrium_minerals = "Calcite Dolomite-ord Muscovite Kaolinite Paragonite Analcime Phlogopite Tridymite" # Dawsonite
    kinetic_minerals = "Quartz"
    kinetic_rate_descriptions = "rate_quartz"
  []
[]
[AuxVariables]
  [diss_rate]
  []
[]
[AuxKernels]
  [diss_rate]
    type = ParsedAux
    args = mol_change_Quartz
    function = '-mol_change_Quartz / 1.0' # 1.0 = timestep size
    variable = diss_rate
  []
[]
[Postprocessors]
  [pH]
    type = PointValue
    variable = "pH"
  []
  [rate_mole_per_day]
    type = PointValue
    variable = diss_rate
  []
  [cm3_Calcite]
    type = PointValue
    variable = free_cm3_Calcite
  []
  [cm3_Dolomite]
    type = PointValue
    variable = free_cm3_Dolomite-ord
  []
  [cm3_Muscovite]
    type = PointValue
    variable = free_cm3_Muscovite
  []
  [cm3_Kaolinite]
    type = PointValue
    variable = free_cm3_Kaolinite
  []
  [cm3_Quartz]
    type = PointValue
    variable = free_cm3_Quartz
  []
  [cm3_Paragonite]
    type = PointValue
    variable = free_cm3_Paragonite
  []
  [cm3_Analcime]
    type = PointValue
    variable = free_cm3_Analcime
  []
  [cm3_Phlogopite]
    type = PointValue
    variable = free_cm3_Phlogopite
  []
  [cm3_Tridymite]
    type = PointValue
    variable = free_cm3_Tridymite
  []
[]
[Executioner]
  type = Transient
  dt = 1
  end_time = 20 # measured in days
[]
[Outputs]
  csv = true
[]
(modules/geochemistry/test/tests/time_dependent_reactions/flushing_case1.i)
# Alkali flushing of a reservoir (an example of flushing): adding NaOH
# To determine the initial constraint_values, run flushing_equilibrium_at70degC.i
# Note that flushing_equilibrium_at70degC.i will have to be re-run when temperature-dependence has been added to geochemistry
# Note that Dawsonite is currently not included as an equilibrium_mineral, otherwise it is supersaturated in the initial configuration, so precipitates.  Bethke does not report this in Fig30.4, so I assume it is due to temperature dependence
[GlobalParams]
  point = '0 0 0'
[]
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  swap_into_basis = "Calcite Dolomite-ord Muscovite Kaolinite"
  swap_out_of_basis = "HCO3- Mg++ K+ Al+++"
  constraint_species = "H2O H+   Cl-       Na+       Ca++       Calcite   Dolomite-ord Muscovite Kaolinite SiO2(aq)"
  constraint_value = "  1.0 1E-5 2.1716946 1.0288941 0.21650572 10.177537 3.6826177    1.320907  1.1432682 6.318e-05"
  constraint_meaning = "kg_solvent_water activity bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition free_concentration"
  constraint_unit = "   kg              dimensionless moles          moles              moles              moles              moles              moles              moles              molal"
  initial_temperature = 70.0
  temperature = 70.0
  kinetic_species_name = Quartz
  kinetic_species_initial_value = 226.992243
  kinetic_species_unit = moles
  evaluate_kinetic_rates_always = true # implicit time-marching used for stability
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  close_system_at_time = 0.0
  remove_fixed_activity_name = "H+"
  remove_fixed_activity_time = 0.0
  mode = 3 # flush through the NaOH solution specified below:
  source_species_names = "H2O    Na+  OH-"
  source_species_rates = "27.755 0.25 0.25" # 1kg water/2days = 27.755moles/day.  0.5mol Na+/2days = 0.25mol/day
[]
[UserObjects]
  [rate_quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1.3824E-13 # 1.6E-19mol/s/cm^2 = 1.3824E-13mol/day/cm^2
    multiply_by_mass = true
    area_quantity = 1000
    promoting_species_names = "H+"
    promoting_species_indices = "-0.5"
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "../../../database/moose_geochemdb.json"
    basis_species = "H2O H+ Cl- Na+ Ca++ HCO3- Mg++ K+ Al+++ SiO2(aq)"
    equilibrium_minerals = "Calcite Dolomite-ord Muscovite Kaolinite Paragonite Analcime Phlogopite Tridymite" # Dawsonite
    kinetic_minerals = "Quartz"
    kinetic_rate_descriptions = "rate_quartz"
  []
[]
[AuxVariables]
  [diss_rate]
  []
[]
[AuxKernels]
  [diss_rate]
    type = ParsedAux
    args = mol_change_Quartz
    function = '-mol_change_Quartz / 1.0' # 1.0 = timestep size
    variable = diss_rate
  []
[]
[Postprocessors]
  [pH]
    type = PointValue
    variable = "pH"
  []
  [rate_mole_per_day]
    type = PointValue
    variable = diss_rate
  []
  [cm3_Calcite]
    type = PointValue
    variable = free_cm3_Calcite
  []
  [cm3_Dolomite]
    type = PointValue
    variable = free_cm3_Dolomite-ord
  []
  [cm3_Muscovite]
    type = PointValue
    variable = free_cm3_Muscovite
  []
  [cm3_Kaolinite]
    type = PointValue
    variable = free_cm3_Kaolinite
  []
  [cm3_Quartz]
    type = PointValue
    variable = free_cm3_Quartz
  []
  [cm3_Paragonite]
    type = PointValue
    variable = free_cm3_Paragonite
  []
  [cm3_Analcime]
    type = PointValue
    variable = free_cm3_Analcime
  []
  [cm3_Phlogopite]
    type = PointValue
    variable = free_cm3_Phlogopite
  []
  [cm3_Tridymite]
    type = PointValue
    variable = free_cm3_Tridymite
  []
[]
[Executioner]
  type = Transient
  dt = 1
  end_time = 20 # measured in days
[]
[Outputs]
  csv = true
[]
(modules/geochemistry/test/tests/time_dependent_reactions/flushing_case3.i)
# Alkali flushing of a reservoir (an example of flushing): adding Na2SiO3
# To determine the initial constraint_values, run flushing_equilibrium_at70degC.i
# Note that flushing_equilibrium_at70degC.i will have to be re-run when temperature-dependence has been added to geochemistry
# Note that Dawsonite is currently not included as an equilibrium_mineral, otherwise it is supersaturated in the initial configuration, so precipitates.  Bethke does not report this in Fig30.4, so I assume it is due to temperature dependence
[GlobalParams]
  point = '0 0 0'
[]
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  swap_into_basis = "Calcite Dolomite-ord Muscovite Kaolinite"
  swap_out_of_basis = "HCO3- Mg++ K+ Al+++"
  constraint_species = "H2O H+   Cl-       Na+       Ca++       Calcite   Dolomite-ord Muscovite Kaolinite SiO2(aq)"
  constraint_value = "  1.0 1E-5 2.1716946 1.0288941 0.21650572 10.177537 3.6826177    1.320907  1.1432682 6.318e-05"
  constraint_meaning = "kg_solvent_water activity bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition bulk_composition free_concentration"
  constraint_unit = "   kg              dimensionless moles          moles              moles              moles              moles              moles              moles              molal"
  initial_temperature = 70.0
  temperature = 70.0
  kinetic_species_name = Quartz
  kinetic_species_initial_value = 226.992243
  kinetic_species_unit = moles
  evaluate_kinetic_rates_always = true # implicit time-marching used for stability
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  close_system_at_time = 0.0
  remove_fixed_activity_name = "H+"
  remove_fixed_activity_time = 0.0
  mode = 3 # flush through the NaOH solution specified below:
  source_species_names = "H2O    H+  Na+   SiO2(aq)"
  source_species_rates = "27.88 -0.25 0.25 0.125" # 1kg water/2days = 27.755moles/day.  0.25mol Na2O/2days = 0.25*(--2mol H+ + 2mol Na+ + 1mol H2O)/2days
[]
[UserObjects]
  [rate_quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1.3824E-13 # 1.6E-19mol/s/cm^2 = 1.3824E-13mol/day/cm^2
    multiply_by_mass = true
    area_quantity = 1000
    promoting_species_names = "H+"
    promoting_species_indices = "-0.5"
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "../../../database/moose_geochemdb.json"
    basis_species = "H2O H+ Cl- Na+ Ca++ HCO3- Mg++ K+ Al+++ SiO2(aq)"
    equilibrium_minerals = "Calcite Dolomite-ord Muscovite Kaolinite Paragonite Analcime Phlogopite Tridymite" # Dawsonite
    kinetic_minerals = "Quartz"
    kinetic_rate_descriptions = "rate_quartz"
  []
[]
[AuxVariables]
  [diss_rate]
  []
[]
[AuxKernels]
  [diss_rate]
    type = ParsedAux
    args = mol_change_Quartz
    function = '-mol_change_Quartz / 1.0' # 1.0 = timestep size
    variable = diss_rate
  []
[]
[Postprocessors]
  [pH]
    type = PointValue
    variable = "pH"
  []
  [rate_mole_per_day]
    type = PointValue
    variable = diss_rate
  []
  [cm3_Calcite]
    type = PointValue
    variable = free_cm3_Calcite
  []
  [cm3_Dolomite]
    type = PointValue
    variable = free_cm3_Dolomite-ord
  []
  [cm3_Muscovite]
    type = PointValue
    variable = free_cm3_Muscovite
  []
  [cm3_Kaolinite]
    type = PointValue
    variable = free_cm3_Kaolinite
  []
  [cm3_Quartz]
    type = PointValue
    variable = free_cm3_Quartz
  []
  [cm3_Paragonite]
    type = PointValue
    variable = free_cm3_Paragonite
  []
  [cm3_Analcime]
    type = PointValue
    variable = free_cm3_Analcime
  []
  [cm3_Phlogopite]
    type = PointValue
    variable = free_cm3_Phlogopite
  []
  [cm3_Tridymite]
    type = PointValue
    variable = free_cm3_Tridymite
  []
[]
[Executioner]
  type = Transient
  dt = 0.1
  end_time = 20E-1 # measured in days
[]
[Outputs]
  csv = true
[]
(modules/geochemistry/test/tests/time_dependent_reactions/flushing.i)
# Alkali flushing of a reservoir (an example of flushing): adding NaOH solution
[UserObjects]
  [rate_quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1.5552E-13 # 1.8E-18mol/s/cm^2 = 1.5552E-13mol/day/cm^2
    multiply_by_mass = true
    area_quantity = 1000
    promoting_species_names = "H+"
    promoting_species_indices = "-0.5"
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "../../../database/moose_geochemdb.json"
    basis_species = "H2O H+ Cl- Na+ Ca++ HCO3- Mg++ K+ Al+++ SiO2(aq)"
    equilibrium_minerals = "Analcime Calcite Dawsonite Dolomite-ord Gibbsite Kaolinite Muscovite Paragonite Phlogopite"
    kinetic_minerals = "Quartz"
    kinetic_rate_descriptions = "rate_quartz"
  []
[]
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  swap_into_basis = "Calcite Dolomite-ord Muscovite Kaolinite"
  swap_out_of_basis = "HCO3- Mg++ K+ Al+++"
  constraint_species = "H2O              H+            Cl-              Na+              Ca++             Calcite      Dolomite-ord Muscovite    Kaolinite    SiO2(aq)"
  constraint_value = "  1.0              -5            1.0              1.0              0.2              9.88249      3.652471265  1.2792268    1.2057878    0.000301950628974"
  constraint_meaning = "kg_solvent_water log10activity bulk_composition bulk_composition bulk_composition free_mineral free_mineral free_mineral free_mineral free_concentration"
  constraint_unit = "   kg               dimensionless moles            moles            moles            moles        moles        moles        moles        molal"
  initial_temperature = 70.0
  temperature = 70.0
  kinetic_species_name = Quartz
  kinetic_species_initial_value = 226.992243
  kinetic_species_unit = moles
  evaluate_kinetic_rates_always = true # implicit time-marching used for stability
  close_system_at_time = 0.0
  remove_fixed_activity_name = "H+"
  remove_fixed_activity_time = 0.0
  mode = 3 # flush through the NaOH solution specified below:
  source_species_names = "H2O   Na+  OH-"
  source_species_rates = "27.75 0.25 0.25" # 1kg water/2days = 27.75moles/day.  0.5mol Na+/2days = 0.25mol/day
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  stoichiometric_ionic_str_using_Cl_only = true
  execute_console_output_on = '' # only CSV output for this test
  abs_tol = 1E-13
[]
[Executioner]
  type = Transient
  dt = 1
  end_time = 20 # measured in days
[]
[GlobalParams]
  point = '0 0 0'
[]
[Postprocessors]
  [pH]
    type = PointValue
    variable = "pH"
  []
  [cm3_Analcime]
    type = PointValue
    variable = free_cm3_Analcime
  []
  [cm3_Calcite]
    type = PointValue
    variable = free_cm3_Calcite
  []
  [cm3_Dawsonite]
    type = PointValue
    variable = free_cm3_Dawsonite
  []
  [cm3_Dolomite]
    type = PointValue
    variable = free_cm3_Dolomite-ord
  []
  [cm3_Gibbsite]
    type = PointValue
    variable = free_cm3_Gibbsite
  []
  [cm3_Kaolinite]
    type = PointValue
    variable = free_cm3_Kaolinite
  []
  [cm3_Muscovite]
    type = PointValue
    variable = free_cm3_Muscovite
  []
  [cm3_Paragonite]
    type = PointValue
    variable = free_cm3_Paragonite
  []
  [cm3_Phlogopite]
    type = PointValue
    variable = free_cm3_Phlogopite
  []
  [cm3_Quartz]
    type = PointValue
    variable = free_cm3_Quartz
  []
[]
[Outputs]
  csv = true
[]
(modules/combined/examples/geochem-porous_flow/forge/reservoir_and_water_3.i)
# Simulation to assess possible changes in the reservoir.  The rock composition from natural_reservoir.i is mixed with the water from water_3.i  Note that the free_concentration values are used from water_3.i and that composition is held fixed throughout this entire simulation.  This models water_3 continually flushing through the rock mineral assemblage: as soon as a mineral dissolves the aqueous components are swept away and replaced by a new batch of water_3; as soon as mineral precipitates more water_3 sweeps into the system providing a limitless source of aqueous components (in set ratios) at 70degC
# The results depend on the kinetic rates used and these are recognised to be poorly constrained by experiment
[UserObjects]
  [rate_Albite]
    type = GeochemistryKineticRate
    kinetic_species_name = Albite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 69.8E3
    one_over_T0 = 0.003354
  []
  [rate_Anhydrite]
    type = GeochemistryKineticRate
    kinetic_species_name = Anhydrite
    intrinsic_rate_constant = 1.0E-7
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 14.3E3
    one_over_T0 = 0.003354
  []
  [rate_Anorthite]
    type = GeochemistryKineticRate
    kinetic_species_name = Anorthite
    intrinsic_rate_constant = 1.0E-13
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 17.8E3
    one_over_T0 = 0.003354
  []
  [rate_Calcite]
    type = GeochemistryKineticRate
    kinetic_species_name = Calcite
    intrinsic_rate_constant = 1.0E-10
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 23.5E3
    one_over_T0 = 0.003354
  []
  [rate_Chalcedony]
    type = GeochemistryKineticRate
    kinetic_species_name = Chalcedony
    intrinsic_rate_constant = 1.0E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 90.1E3
    one_over_T0 = 0.003354
  []
  [rate_Clinochl-7A]
    type = GeochemistryKineticRate
    kinetic_species_name = Clinochl-7A
    intrinsic_rate_constant = 1.0E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 88.0E3
    one_over_T0 = 0.003354
  []
  [rate_Illite]
    type = GeochemistryKineticRate
    kinetic_species_name = Illite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 29E3
    one_over_T0 = 0.003354
  []
  [rate_K-feldspar]
    type = GeochemistryKineticRate
    kinetic_species_name = K-feldspar
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 38E3
    one_over_T0 = 0.003354
  []
  [rate_Kaolinite]
    type = GeochemistryKineticRate
    kinetic_species_name = Kaolinite
    intrinsic_rate_constant = 1E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22.2E3
    one_over_T0 = 0.003354
  []
  [rate_Quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 90.1E3
    one_over_T0 = 0.003354
  []
  [rate_Paragonite]
    type = GeochemistryKineticRate
    kinetic_species_name = Paragonite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22E3
    one_over_T0 = 0.003354
  []
  [rate_Phlogopite]
    type = GeochemistryKineticRate
    kinetic_species_name = Phlogopite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22E3
    one_over_T0 = 0.003354
  []
  [rate_Laumontite]
    type = GeochemistryKineticRate
    kinetic_species_name = Laumontite
    intrinsic_rate_constant = 1.0E-15
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 17.8E3
    one_over_T0 = 0.003354
  []
  [rate_Zoisite]
    type = GeochemistryKineticRate
    kinetic_species_name = Zoisite
    intrinsic_rate_constant = 1E-16
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 66.1E3
    one_over_T0 = 0.003354
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = '../../../../geochemistry/database/moose_geochemdb.json'
    basis_species = 'H2O H+ Na+ K+ Ca++ Mg++ SiO2(aq) Al+++ Cl- SO4-- HCO3-'
    remove_all_extrapolated_secondary_species = true
    kinetic_minerals = 'Albite Anhydrite Anorthite Calcite Chalcedony Clinochl-7A Illite K-feldspar Kaolinite Quartz Paragonite Phlogopite Zoisite Laumontite'
    kinetic_rate_descriptions = 'rate_Albite rate_Anhydrite rate_Anorthite rate_Calcite rate_Chalcedony rate_Clinochl-7A rate_Illite rate_K-feldspar rate_Kaolinite rate_Quartz rate_Paragonite rate_Phlogopite rate_Zoisite rate_Laumontite'
  []
[]
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = 'Cl-'
  constraint_species = 'H2O              H+                  Na+                K+                  Ca++                Mg++               SiO2(aq)            Al+++               Cl-                SO4--               HCO3-'
# Following numbers are from water_3_out.csv
  constraint_value = '  0.99999999549877 8.0204734722945e-07 0.0001319920398478 2.8097346859027e-05 7.7328020546464e-05 2.874602030221e-05 0.00027284654762868 4.4715524787497e-12 0.0002253530818877 1.0385772502298e-05 0.00012427759434288'
  constraint_meaning = 'kg_solvent_water free_concentration       free_concentration    free_concentration      free_concentration     free_concentration       free_concentration      free_concentration       bulk_composition free_concentration       free_concentration'
  constraint_unit = '   kg               molal               molal            molal              molal             molal               molal              molal               moles              molal               molal'
  initial_temperature = 70
  temperature = 70
  close_system_at_time = 1E20 # keep the free molalities specified above for all time
  kinetic_species_name = '         Albite             Anorthite          K-feldspar         Quartz             Phlogopite         Paragonite         Calcite            Anhydrite          Chalcedony         Illite             Kaolinite          Clinochl-7A        Zoisite            Laumontite'
  kinetic_species_initial_value = '4.324073236492E+02 4.631370307325E+01 2.685015418378E+02 7.720095013956E+02 1.235192062541E+01 7.545461404965E-01 4.234651808835E-04 4.000485907930E-04 4.407616361072E+00 1.342524904876E+01 1.004823151125E+00 4.728132387707E-01 7.326007326007E-01 4.818116116598E-01'
  kinetic_species_unit = '         moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles'
  evaluate_kinetic_rates_always = true # otherwise will easily "run out" of dissolving species
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  execute_console_output_on = ''
[]
[Executioner]
  type = Transient
  [TimeStepper]
    type = FunctionDT
    function = 'max(1E6, 0.3 * t)'
  []
  end_time = 4E11
[]
[GlobalParams]
  point = '0 0 0'
[]
[Postprocessors]
  [temperature]
    type = PointValue
    variable = 'solution_temperature'
  []
  [cm3_Albite]
    type = PointValue
    variable = 'free_cm3_Albite'
  []
  [cm3_Anhydrite]
    type = PointValue
    variable = 'free_cm3_Anhydrite'
  []
  [cm3_Anorthite]
    type = PointValue
    variable = 'free_cm3_Anorthite'
  []
  [cm3_Calcite]
    type = PointValue
    variable = 'free_cm3_Calcite'
  []
  [cm3_Chalcedony]
    type = PointValue
    variable = 'free_cm3_Chalcedony'
  []
  [cm3_Clinochl-7A]
    type = PointValue
    variable = 'free_cm3_Clinochl-7A'
  []
  [cm3_Illite]
    type = PointValue
    variable = 'free_cm3_Illite'
  []
  [cm3_K-feldspar]
    type = PointValue
    variable = 'free_cm3_K-feldspar'
  []
  [cm3_Kaolinite]
    type = PointValue
    variable = 'free_cm3_Kaolinite'
  []
  [cm3_Quartz]
    type = PointValue
    variable = 'free_cm3_Quartz'
  []
  [cm3_Paragonite]
    type = PointValue
    variable = 'free_cm3_Paragonite'
  []
  [cm3_Phlogopite]
    type = PointValue
    variable = 'free_cm3_Phlogopite'
  []
  [cm3_Zoisite]
    type = PointValue
    variable = 'free_cm3_Zoisite'
  []
  [cm3_Laumontite]
    type = PointValue
    variable = 'free_cm3_Laumontite'
  []
  [cm3_mineral]
    type = LinearCombinationPostprocessor
    pp_names = 'cm3_Albite cm3_Anhydrite cm3_Anorthite cm3_Calcite cm3_Chalcedony cm3_Clinochl-7A cm3_Illite cm3_K-feldspar cm3_Kaolinite cm3_Quartz cm3_Paragonite cm3_Phlogopite cm3_Zoisite cm3_Laumontite'
    pp_coefs = '1 1 1 1 1 1 1 1 1 1 1 1 1 1'
  []
  [pH]
    type = PointValue
    variable = 'pH'
  []
[]
[Outputs]
  csv = true
[]
(modules/geochemistry/test/tests/kinetics/quartz_dissolution.i)
# Example of quartz dissolution.
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  constraint_species = "H2O              H+               Cl-              SiO2(aq)"
  constraint_value = "  1.0              1E-10            1E-10            1E-9"
  constraint_meaning = "kg_solvent_water bulk_composition bulk_composition free_concentration"
  constraint_unit = "   kg               moles            moles            molal"
  initial_temperature = 100.0
  temperature = 100.0
  kinetic_species_name = Quartz
  kinetic_species_initial_value = 5
  kinetic_species_unit = kg
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  stoichiometric_ionic_str_using_Cl_only = true # for comparison with GWB
  execute_console_output_on = '' # only CSV output for this example
[]
[UserObjects]
  [rate_quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1.728E-10 # 2.0E-15mol/s/cm^2 = 1.728E-10mol/day/cm^2
    multiply_by_mass = true
    area_quantity = 1000
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "../../../database/moose_geochemdb.json"
    basis_species = "H2O SiO2(aq) H+ Cl-"
    kinetic_minerals = "Quartz"
    kinetic_rate_descriptions = "rate_quartz"
    piecewise_linear_interpolation = true # for comparison with GWB
  []
[]
[Functions]
  [timestepper]
    type = PiecewiseLinear
    x = '0 0.5 3'
    y = '0.01 0.05 0.1'
  []
[]
[Executioner]
  type = Transient
  [TimeStepper]
    type = FunctionDT
    function = timestepper
  []
  end_time = 5.0
[]
[AuxVariables]
  [diss]
  []
[]
[AuxKernels]
  [diss]
    type = ParsedAux
    args = moles_Quartz
    function = '83.216414271 - moles_Quartz'
    variable = diss
  []
[]
[Postprocessors]
  [dissolved_moles]
    type = PointValue
    point = '0 0 0'
    variable = diss
  []
[]
[Outputs]
  csv = true
[]
(modules/combined/examples/geochem-porous_flow/geotes_2D/aquifer_geochemistry.i)
# Simulates geochemistry in the aquifer.  This input file may be run in standalone fashion but it does not do anything of interest.  To simulate something interesting, run the porous_flow.i simulation which couples to this input file using MultiApps.
# This file receives pf_rate_H2O, pf_rate_Na, pf_rate_Cl, pf_rate_SiO2 and temperature as AuxVariables from porous_flow.i.
# The pf_rate quantities are kg/s changes of fluid-component mass at each node, but the geochemistry module expects rates-of-changes of moles at every node.  Secondly, since this input file considers just 1 litre of aqueous solution at every node, the nodal_void_volume is used to convert pf_rate_* into rate_*_per_1l, which is measured in mol/s/1_litre_of_aqueous_solution.
# This file sends massfrac_Na, massfrac_Cl and massfrac_SiO2 to porous_flow.i.  These are computed from the corresponding transported_* quantities.
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    nx = 14 # for better resolution, use 56 or 112
    ny = 8  # for better resolution, use 32 or 64
    xmin = -70
    xmax = 70
    ymin = -40
    ymax = 40
  []
[]
[GlobalParams]
  point = '0 0 0'
  reactor = reactor
[]
[SpatialReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  constraint_species = "H2O              Na+              Cl-              SiO2(aq)"
# ASSUME that 1 litre of solution contains:
  constraint_value = "  1.0              0.1              0.1              0.000555052386"
  constraint_meaning = "kg_solvent_water bulk_composition bulk_composition free_concentration"
  constraint_unit = "   kg               moles            moles            molal"
  initial_temperature = 50.0
  kinetic_species_name = QuartzLike
# Per 1 litre (1000cm^3) of aqueous solution (1kg of solvent water), there is 9000cm^3 of QuartzLike, which means the initial porosity is 0.1.
  kinetic_species_initial_value = 9000
  kinetic_species_unit = cm3
  temperature = temperature
  source_species_names = 'H2O    Na+   Cl-   SiO2(aq)'
  source_species_rates = 'rate_H2O_per_1l rate_Na_per_1l rate_Cl_per_1l rate_SiO2_per_1l'
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  add_aux_pH = false # there is no H+ in this system
  evaluate_kinetic_rates_always = true # implicit time-marching used for stability
  execute_console_output_on = ''
[]
[UserObjects]
  [rate_quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = QuartzLike
    intrinsic_rate_constant = 1.0E-2
    multiply_by_mass = true
    area_quantity = 1
    activation_energy = 72800.0
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "small_database.json"
    basis_species = "H2O SiO2(aq) Na+ Cl-"
    kinetic_minerals = "QuartzLike"
    kinetic_rate_descriptions = "rate_quartz"
  []
  [nodal_void_volume_uo]
    type = NodalVoidVolume
    porosity = porosity
    execute_on = 'initial timestep_end' # "initial" means this is evaluated properly for the first timestep
  []
[]
[Executioner]
  type = Transient
  dt = 1E5
  end_time = 7.76E6 # 90 days
[]
[AuxVariables]
  [temperature]
    initial_condition = 50.0
  []
  [porosity]
    initial_condition = 0.1
  []
  [nodal_void_volume]
  []
  [pf_rate_H2O] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [pf_rate_Na] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [pf_rate_Cl] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [pf_rate_SiO2] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [rate_H2O_per_1l] # rate per 1 litre of aqueous solution that we consider at each node
  []
  [rate_Na_per_1l]
  []
  [rate_Cl_per_1l]
  []
  [rate_SiO2_per_1l]
  []
  [transported_H2O]
  []
  [transported_Na]
  []
  [transported_Cl]
  []
  [transported_SiO2]
  []
  [transported_mass]
  []
  [massfrac_Na]
  []
  [massfrac_Cl]
  []
  [massfrac_SiO2]
  []
  [massfrac_H2O]
  []
[]
[AuxKernels]
  [porosity]
    type = ParsedAux
    args = free_cm3_QuartzLike
    function = '1000.0 / (1000.0 + free_cm3_QuartzLike)'
    variable = porosity
    execute_on = 'timestep_end'
  []
  [nodal_void_volume_auxk]
    type = NodalVoidVolumeAux
    variable = nodal_void_volume
    nodal_void_volume_uo = nodal_void_volume_uo
    execute_on = 'initial timestep_end' # "initial" to ensure it is properly evaluated for the first timestep
  []
  [rate_H2O_per_1l_auxk]
    type = ParsedAux
    args = 'pf_rate_H2O nodal_void_volume'
    variable = rate_H2O_per_1l
# pf_rate = change in kg at every node
# pf_rate * 1000 / molar_mass_in_g_per_mole = change in moles at every node
# pf_rate * 1000 / molar_mass / (nodal_void_volume_in_m^3 * 1000) = change in moles per litre of aqueous solution
    function = 'pf_rate_H2O / 18.0152 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Na_per_1l]
    type = ParsedAux
    args = 'pf_rate_Na nodal_void_volume'
    variable = rate_Na_per_1l
    function = 'pf_rate_Na / 22.9898 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Cl_per_1l]
    type = ParsedAux
    args = 'pf_rate_Cl nodal_void_volume'
    variable = rate_Cl_per_1l
    function = 'pf_rate_Cl / 35.453 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_SiO2_per_1l]
    type = ParsedAux
    args = 'pf_rate_SiO2 nodal_void_volume'
    variable = rate_SiO2_per_1l
    function = 'pf_rate_SiO2 / 60.0843 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [transported_H2O_auxk]
    type = GeochemistryQuantityAux
    variable = transported_H2O
    species = H2O
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_end'
  []
  [transported_Na]
    type = GeochemistryQuantityAux
    variable = transported_Na
    species = Na+
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_end'
  []
  [transported_Cl]
    type = GeochemistryQuantityAux
    variable = transported_Cl
    species = Cl-
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_end'
  []
  [transported_SiO2]
    type = GeochemistryQuantityAux
    variable = transported_SiO2
    species = 'SiO2(aq)'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_end'
  []
  [transported_mass_auxk]
    type = ParsedAux
    args = 'transported_H2O transported_Na transported_Cl transported_SiO2'
    variable = transported_mass
    function = 'transported_H2O * 18.0152 + transported_Na * 22.9898 + transported_Cl * 35.453 + transported_SiO2 * 60.0843'
    execute_on = 'timestep_end'
  []
  [massfrac_H2O]
    type = ParsedAux
    args = 'transported_H2O transported_mass'
    variable = massfrac_H2O
    function = 'transported_H2O * 18.0152 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Na]
    type = ParsedAux
    args = 'transported_Na transported_mass'
    variable = massfrac_Na
    function = 'transported_Na * 22.9898 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Cl]
    type = ParsedAux
    args = 'transported_Cl transported_mass'
    variable = massfrac_Cl
    function = 'transported_Cl * 35.453 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_SiO2]
    type = ParsedAux
    args = 'transported_SiO2 transported_mass'
    variable = massfrac_SiO2
    function = 'transported_SiO2 * 60.0843 / transported_mass'
    execute_on = 'timestep_end'
  []
[]
[Postprocessors]
  [cm3_quartz]
    type = PointValue
    variable = free_cm3_QuartzLike
  []
  [porosity]
    type = PointValue
    variable = porosity
  []
  [solution_temperature]
    type = PointValue
    variable = solution_temperature
  []
  [massfrac_H2O]
    type = PointValue
    variable = massfrac_H2O
  []
  [massfrac_Na]
    type = PointValue
    variable = massfrac_Na
  []
  [massfrac_Cl]
    type = PointValue
    variable = massfrac_Cl
  []
  [massfrac_SiO2]
    type = PointValue
    variable = massfrac_SiO2
  []
[]
[Outputs]
  exodus = true
  csv = true
[]
(modules/combined/examples/geochem-porous_flow/forge/natural_reservoir.i)
# Simulation to assess natural changes in the reservoir.  Recall that water_60_to_220degC has provided a stable mineral assemblage that is in agreement with XRD observations, and a water at equilibrium with that assemblage.  However, Stuart Simmons suggested including Laumontite and Zoisite into the simulation, and they were not included in water_60_to_220degC since they are more stable than Anorthite, so Anorthite completely dissolves when equilibrium is assumed.  Here, all minerals suggested by Stuart Simmons are added to the system and kinetics are used to determine the time scales of the mineral changes.  The initial water composition is the reservoir water from water_60_to_220degC.
# The initial mole numbers of the kinetic species are chosen to be such that:
# - the mass fractions are: Albite 0.44; Anorthite 0.05; K-feldspar 0.29; Quartz 0.18, Phlgoptite 0.02 and Illite 0.02 with trace amounts of the remaining minerals.  These are similar to that measured in bulk X-ray diffraction results of 10 samples from well 58-32, assuming that "plagioclase feldspar" consists of Albite and Anorthite in the ratio 9:1, and that Biotite is Phlogoptite.  The trace amounts of each mineral are necessary because of the way the kinetics works: precipitation rate is proportional to mineral-species mass, so without any mass, no precipitation is possible.  Precisely:
# - it is assumed that water_60_to_220degC consists of 1 litre of water (there is 1kg of solvent water) and that the porosity is 0.01, so the amount of rock should be 99000cm^3
# - the cm^3 of the trace minerals Calcite and Anhydrite is exactly given by water_60_to_220degC (0.016 and 0.018 respectively)
# - see initial_kinetic_moles.xlsx for the remaining mole numbers
# The results depend on the kinetic rates used and these are recognised to be poorly constrained by experiment
[UserObjects]
  [rate_Albite]
    type = GeochemistryKineticRate
    kinetic_species_name = Albite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 69.8E3
    one_over_T0 = 0.003354
  []
  [rate_Anhydrite]
    type = GeochemistryKineticRate
    kinetic_species_name = Anhydrite
    intrinsic_rate_constant = 1.0E-7
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 14.3E3
    one_over_T0 = 0.003354
  []
  [rate_Anorthite]
    type = GeochemistryKineticRate
    kinetic_species_name = Anorthite
    intrinsic_rate_constant = 1.0E-13
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 17.8E3
    one_over_T0 = 0.003354
  []
  [rate_Calcite]
    type = GeochemistryKineticRate
    kinetic_species_name = Calcite
    intrinsic_rate_constant = 1.0E-10
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 23.5E3
    one_over_T0 = 0.003354
  []
  [rate_Chalcedony]
    type = GeochemistryKineticRate
    kinetic_species_name = Chalcedony
    intrinsic_rate_constant = 1.0E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 90.1E3
    one_over_T0 = 0.003354
  []
  [rate_Clinochl-7A]
    type = GeochemistryKineticRate
    kinetic_species_name = Clinochl-7A
    intrinsic_rate_constant = 1.0E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 88.0E3
    one_over_T0 = 0.003354
  []
  [rate_Illite]
    type = GeochemistryKineticRate
    kinetic_species_name = Illite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 29E3
    one_over_T0 = 0.003354
  []
  [rate_K-feldspar]
    type = GeochemistryKineticRate
    kinetic_species_name = K-feldspar
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 38E3
    one_over_T0 = 0.003354
  []
  [rate_Kaolinite]
    type = GeochemistryKineticRate
    kinetic_species_name = Kaolinite
    intrinsic_rate_constant = 1E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22.2E3
    one_over_T0 = 0.003354
  []
  [rate_Quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = Quartz
    intrinsic_rate_constant = 1E-18
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 90.1E3
    one_over_T0 = 0.003354
  []
  [rate_Paragonite]
    type = GeochemistryKineticRate
    kinetic_species_name = Paragonite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22E3
    one_over_T0 = 0.003354
  []
  [rate_Phlogopite]
    type = GeochemistryKineticRate
    kinetic_species_name = Phlogopite
    intrinsic_rate_constant = 1E-17
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 22E3
    one_over_T0 = 0.003354
  []
  [rate_Laumontite]
    type = GeochemistryKineticRate
    kinetic_species_name = Laumontite
    intrinsic_rate_constant = 1.0E-15
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 17.8E3
    one_over_T0 = 0.003354
  []
  [rate_Zoisite]
    type = GeochemistryKineticRate
    kinetic_species_name = Zoisite
    intrinsic_rate_constant = 1E-16
    multiply_by_mass = true
    area_quantity = 10
    activation_energy = 66.1E3
    one_over_T0 = 0.003354
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = '../../../../geochemistry/database/moose_geochemdb.json'
    basis_species = 'H2O H+ Na+ K+ Ca++ Mg++ SiO2(aq) Al+++ Cl- SO4-- HCO3-'
    remove_all_extrapolated_secondary_species = true
    kinetic_minerals = 'Albite Anhydrite Anorthite Calcite Chalcedony Clinochl-7A Illite K-feldspar Kaolinite Quartz Paragonite Phlogopite Zoisite Laumontite'
    kinetic_rate_descriptions = 'rate_Albite rate_Anhydrite rate_Anorthite rate_Calcite rate_Chalcedony rate_Clinochl-7A rate_Illite rate_K-feldspar rate_Kaolinite rate_Quartz rate_Paragonite rate_Phlogopite rate_Zoisite rate_Laumontite'
  []
[]
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = 'Cl-'
  constraint_species = 'H2O              H+                  Na+                K+                 Ca++               Mg++                SiO2(aq)           Al+++               Cl-              SO4--               HCO3-'
# Following numbers are from water_60_to_220degC_out.csv
  constraint_value = '  1.0006383866109  9.5165072498215e-07 0.100020379171     0.0059389061065    0.011570884507621  4.6626763057447e-06 0.0045110404925255 5.8096968688789e-17 0.13500708594394 6.6523540147676e-05 7.7361407898089e-05'
  constraint_meaning = 'kg_solvent_water free_concentration  free_concentration free_concentration free_concentration free_concentration  free_concentration free_concentration  bulk_composition free_concentration  free_concentration'
  constraint_unit = '   kg               molal               molal              molal              molal              molal               molal              molal               moles            molal               molal'
  initial_temperature = 220
  temperature = 220
  kinetic_species_name = '         Albite             Anorthite          K-feldspar         Quartz             Phlogopite         Paragonite         Calcite            Anhydrite          Chalcedony         Illite             Kaolinite          Clinochl-7A        Zoisite            Laumontite'
  kinetic_species_initial_value = '4.324073236492E+02 4.631370307325E+01 2.685015418378E+02 7.720095013956E+02 1.235192062541E+01 7.545461404965E-01 4.234651808835E-04 4.000485907930E-04 4.407616361072E+00 1.342524904876E+01 1.004823151125E+00 4.728132387707E-01 7.326007326007E-01 4.818116116598E-01'
  kinetic_species_unit = '         moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles              moles'
  evaluate_kinetic_rates_always = true # otherwise will easily "run out" of dissolving species
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  execute_console_output_on = ''
[]
[Executioner]
  type = Transient
  [TimeStepper]
    type = FunctionDT
    function = 'max(1E2, 0.1 * t)'
  []
  end_time = 4E11
[]
[GlobalParams]
  point = '0 0 0'
[]
[Postprocessors]
  [cm3_Albite]
    type = PointValue
    variable = 'free_cm3_Albite'
  []
  [cm3_Anhydrite]
    type = PointValue
    variable = 'free_cm3_Anhydrite'
  []
  [cm3_Anorthite]
    type = PointValue
    variable = 'free_cm3_Anorthite'
  []
  [cm3_Calcite]
    type = PointValue
    variable = 'free_cm3_Calcite'
  []
  [cm3_Chalcedony]
    type = PointValue
    variable = 'free_cm3_Chalcedony'
  []
  [cm3_Clinochl-7A]
    type = PointValue
    variable = 'free_cm3_Clinochl-7A'
  []
  [cm3_Illite]
    type = PointValue
    variable = 'free_cm3_Illite'
  []
  [cm3_K-feldspar]
    type = PointValue
    variable = 'free_cm3_K-feldspar'
  []
  [cm3_Kaolinite]
    type = PointValue
    variable = 'free_cm3_Kaolinite'
  []
  [cm3_Quartz]
    type = PointValue
    variable = 'free_cm3_Quartz'
  []
  [cm3_Paragonite]
    type = PointValue
    variable = 'free_cm3_Paragonite'
  []
  [cm3_Phlogopite]
    type = PointValue
    variable = 'free_cm3_Phlogopite'
  []
  [cm3_Zoisite]
    type = PointValue
    variable = 'free_cm3_Zoisite'
  []
  [cm3_Laumontite]
    type = PointValue
    variable = 'free_cm3_Laumontite'
  []
  [cm3_mineral]
    type = LinearCombinationPostprocessor
    pp_names = 'cm3_Albite cm3_Anhydrite cm3_Anorthite cm3_Calcite cm3_Chalcedony cm3_Clinochl-7A cm3_Illite cm3_K-feldspar cm3_Kaolinite cm3_Quartz cm3_Paragonite cm3_Phlogopite cm3_Zoisite cm3_Laumontite'
    pp_coefs = '1 1 1 1 1 1 1 1 1 1 1 1 1 1'
  []
  [pH]
    type = PointValue
    variable = 'pH'
  []
  [kg_solvent_H2O]
    type = PointValue
    variable = 'kg_solvent_H2O'
  []
[]
[Outputs]
  csv = true
[]
(modules/geochemistry/test/tests/kinetics/kinetic_albite.i)
# Example of kinetically-controlled dissolution of albite into an acidic solution
[TimeDependentReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  constraint_species = "H2O              H+            Cl-              Na+              SiO2(aq)           Al+++"
  constraint_value = "  1.0              -1.5          0.1              0.1              1E-6               1E-6"
  constraint_meaning = "kg_solvent_water log10activity bulk_composition bulk_composition free_concentration free_concentration"
  constraint_unit = "   kg               dimensionless moles            moles            molal              molal"
  initial_temperature = 70.0
  temperature = 70.0
  kinetic_species_name = Albite
  kinetic_species_initial_value = 250
  kinetic_species_unit = g
  evaluate_kinetic_rates_always = true # implicit time-marching used for stability
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  stoichiometric_ionic_str_using_Cl_only = true # for comparison with GWB
  execute_console_output_on = '' # only CSV output for this example
[]
[UserObjects]
  [rate_albite]
    type = GeochemistryKineticRate
    kinetic_species_name = Albite
    intrinsic_rate_constant = 5.4432E-8 # 6.3E-13mol/s/cm^2 = 5.4432E-8mol/day/cm^2
    multiply_by_mass = true
    area_quantity = 1000
    promoting_species_names = "H+"
    promoting_species_indices = "1.0"
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "../../../database/moose_geochemdb.json"
    basis_species = "H2O H+ Cl- Na+ SiO2(aq) Al+++"
    kinetic_minerals = "Albite"
    kinetic_rate_descriptions = "rate_albite"
  []
[]
[Executioner]
  type = Transient
  dt = 5
  end_time = 30 # measured in days
[]
[AuxVariables]
  [mole_change_albite]
  []
[]
[AuxKernels]
  [mole_change_albite]
    type = ParsedAux
    args = moles_Albite
    function = 'moles_Albite - 0.953387'
    variable = mole_change_albite
  []
[]
[Postprocessors]
  [mole_change_Albite]
    type = PointValue
    point = '0 0 0'
    variable = "mole_change_albite"
  []
[]
[Outputs]
  csv = true
[]
(modules/combined/examples/geochem-porous_flow/geotes_2D/aquifer_un_quartz_geochemistry.i)
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    nx = 56
    ny = 32
    xmin = -70
    xmax = 70
    ymin = -40
    ymax = 40
  []
[]
[GlobalParams]
  point = '0 0 0'
  reactor = reactor
[]
[SpatialReactionSolver]
  model_definition = definition
  geochemistry_reactor_name = reactor
  charge_balance_species = "Cl-"
  constraint_species = "H2O              Na+                Cl-                SiO2(aq)"
# ASSUME that 1 litre of solution contains:
  constraint_value = "  1.0              0.1                0.1                0.00172249633"
  constraint_meaning = "kg_solvent_water bulk_composition bulk_composition free_concentration"
  constraint_unit = "   kg               moles              moles              molal"
  initial_temperature = 50.0
  kinetic_species_name = QuartzUnlike
# Per 1 litre (1000cm^3) of aqueous solution (1kg of solvent water), there is 9000cm^3 of QuartzUnlike, which means the initial porosity is 0.1.
  kinetic_species_initial_value = 9000
  kinetic_species_unit = cm3
  temperature = temperature
  source_species_names = 'H2O    Na+   Cl-   SiO2(aq)'
  source_species_rates = 'rate_H2O_per_1l rate_Na_per_1l rate_Cl_per_1l rate_SiO2_per_1l'
  ramp_max_ionic_strength_initial = 0 # max_ionic_strength in such a simple problem does not need ramping
  add_aux_pH = false # there is no H+ in this system
  evaluate_kinetic_rates_always = true # implicit time-marching used for stability
  execute_console_output_on = '' # only CSV and exodus output used in this example
[]
[UserObjects]
  [rate_quartz]
    type = GeochemistryKineticRate
    kinetic_species_name = QuartzUnlike
    intrinsic_rate_constant = 1.0E-2
    multiply_by_mass = true
    area_quantity = 1
    activation_energy = 72800.0
  []
  [definition]
    type = GeochemicalModelDefinition
    database_file = "small_database.json"
    basis_species = "H2O SiO2(aq) Na+ Cl-"
    kinetic_minerals = "QuartzUnlike"
    kinetic_rate_descriptions = "rate_quartz"
  []
[]
[Executioner]
  type = Transient
  dt = 1E5
  end_time = 7.76E6 # 90 days
[]
[AuxVariables]
  [temperature]
    initial_condition = 50.0
  []
  [nodal_volume]
  []
  [porosity]
  []
  [nodal_void_volume]
  []
  [pf_rate_H2O] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [pf_rate_Na] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [pf_rate_Cl] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [pf_rate_SiO2] # change in H2O mass (kg/s) at each node provided by the porous-flow simulation
  []
  [rate_H2O_per_1l] # rate per 1 litre of aqueous solution that we consider at each node
  []
  [rate_Na_per_1l]
  []
  [rate_Cl_per_1l]
  []
  [rate_SiO2_per_1l]
  []
  [transported_H2O]
  []
  [transported_Na]
  []
  [transported_Cl]
  []
  [transported_SiO2]
  []
  [transported_mass]
  []
  [massfrac_Na]
  []
  [massfrac_Cl]
  []
  [massfrac_SiO2]
  []
  [massfrac_H2O]
  []
[]
[AuxKernels]
  [nodal_volume] # TODO: change this hard-coded version once PR is merged
    type = FunctionAux
    variable = nodal_volume
    function = 'if(abs(x) = 70 & abs(y) = 40, 2.5, if(abs(x) = 70 | abs(y) = 40, 5, 10))'
    execute_on = 'initial'
  []
  [porosity]
    type = ParsedAux
    args = free_cm3_QuartzUnlike
    function = '1000.0 / (1000.0 + free_cm3_QuartzUnlike)'
    variable = porosity
    execute_on = 'timestep_begin timestep_end'
  []
  [nodal_void_volume]
    type = ParsedAux
    args = 'porosity nodal_volume'
    variable = nodal_void_volume
    function = 'porosity * nodal_volume'
    execute_on = 'timestep_begin'
  []
  [rate_H2O_per_1l]
    type = ParsedAux
    args = 'pf_rate_H2O nodal_void_volume'
    variable = rate_H2O_per_1l
# pf_rate = change in kg at every node
# pf_rate * 1000 / molar_mass_in_g_per_mole = change in moles at every node
# pf_rate * 1000 / molar_mass / (nodal_void_volume_in_m^3 * 1000) = change in moles per litre of aqueous solution
    function = 'pf_rate_H2O / 18.0152 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Na_per_1l]
    type = ParsedAux
    args = 'pf_rate_Na nodal_void_volume'
    variable = rate_Na_per_1l
    function = 'pf_rate_Na / 22.9898 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_Cl_per_1l]
    type = ParsedAux
    args = 'pf_rate_Cl nodal_void_volume'
    variable = rate_Cl_per_1l
    function = 'pf_rate_Cl / 35.453 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [rate_SiO2_per_1l]
    type = ParsedAux
    args = 'pf_rate_SiO2 nodal_void_volume'
    variable = rate_SiO2_per_1l
    function = 'pf_rate_SiO2 / 60.0843 / nodal_void_volume'
    execute_on = 'timestep_begin'
  []
  [transported_H2O]
    type = GeochemistryQuantityAux
    variable = transported_H2O
    species = H2O
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_end'
  []
  [transported_Na]
    type = GeochemistryQuantityAux
    variable = transported_Na
    species = Na+
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_end'
  []
  [transported_Cl]
    type = GeochemistryQuantityAux
    variable = transported_Cl
    species = Cl-
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_end'
  []
  [transported_SiO2]
    type = GeochemistryQuantityAux
    variable = transported_SiO2
    species = 'SiO2(aq)'
    quantity = transported_moles_in_original_basis
    execute_on = 'timestep_end'
  []
  [transported_mass]
    type = ParsedAux
    args = 'transported_H2O transported_Na transported_Cl transported_SiO2'
    variable = transported_mass
    function = 'transported_H2O * 18.0152 + transported_Na * 22.9898 + transported_Cl * 35.453 + transported_SiO2 * 60.0843'
    execute_on = 'timestep_end'
  []
  [massfrac_H2O]
    type = ParsedAux
    args = 'transported_H2O transported_mass'
    variable = massfrac_H2O
    function = 'transported_H2O * 18.0152 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Na]
    type = ParsedAux
    args = 'transported_Na transported_mass'
    variable = massfrac_Na
    function = 'transported_Na * 22.9898 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_Cl]
    type = ParsedAux
    args = 'transported_Cl transported_mass'
    variable = massfrac_Cl
    function = 'transported_Cl * 35.453 / transported_mass'
    execute_on = 'timestep_end'
  []
  [massfrac_SiO2]
    type = ParsedAux
    args = 'transported_SiO2 transported_mass'
    variable = massfrac_SiO2
    function = 'transported_SiO2 * 60.0843 / transported_mass'
    execute_on = 'timestep_end'
  []
[]
[Postprocessors]
  [cm3_quartz]
    type = PointValue
    variable = free_cm3_QuartzUnlike
  []
  [porosity]
    type = PointValue
    variable = porosity
  []
  [solution_temperature]
    type = PointValue
    variable = solution_temperature
  []
  [massfrac_H2O]
    type = PointValue
    variable = massfrac_H2O
  []
  [massfrac_Na]
    type = PointValue
    variable = massfrac_Na
  []
  [massfrac_Cl]
    type = PointValue
    variable = massfrac_Cl
  []
  [massfrac_SiO2]
    type = PointValue
    variable = massfrac_SiO2
  []
[]
[Outputs]
  exodus = true
  csv = true
[]