- PorousFlowDictatorThe UserObject that holds the list of PorousFlow variable names
C++ Type:UserObjectName
Controllable:No
Description:The UserObject that holds the list of PorousFlow variable names
 - activation_energyActivation energy, J/mol (one for each reaction)
C++ Type:std::vector<double>
Unit:(no unit assumed)
Controllable:No
Description:Activation energy, J/mol (one for each reaction)
 - equilibrium_constantsEquilibrium constant for each equation (dimensionless). If these are temperature dependent AuxVariables, the Jacobian will not be exact
C++ Type:std::vector<VariableName>
Unit:(no unit assumed)
Controllable:No
Description:Equilibrium constant for each equation (dimensionless). If these are temperature dependent AuxVariables, the Jacobian will not be exact
 - kinetic_rate_constantKinetic rate constant in mol/(m^2 s), at the reference temperature (one for each reaction)
C++ Type:std::vector<double>
Unit:(no unit assumed)
Controllable:No
Description:Kinetic rate constant in mol/(m^2 s), at the reference temperature (one for each reaction)
 - molar_volumeVolume occupied by one mole of the secondary species (L(solution)/mol) (one for each reaction)
C++ Type:std::vector<double>
Unit:(no unit assumed)
Controllable:No
Description:Volume occupied by one mole of the secondary species (L(solution)/mol) (one for each reaction)
 - num_reactionsNumber of equations in the system of chemical reactions
C++ Type:unsigned int
Controllable:No
Description:Number of equations in the system of chemical reactions
 - primary_activity_coefficientsActivity coefficients for the primary species (dimensionless) (one for each)
C++ Type:std::vector<double>
Unit:(no unit assumed)
Controllable:No
Description:Activity coefficients for the primary species (dimensionless) (one for each)
 - primary_concentrationsList of MOOSE Variables that represent the concentrations of the primary species
C++ Type:std::vector<VariableName>
Unit:(no unit assumed)
Controllable:No
Description:List of MOOSE Variables that represent the concentrations of the primary species
 - reactionsA matrix defining the aqueous reactions. The matrix is entered as a long vector: the first row is entered first, followed by the second row, etc. There should be num_reactions rows. All primary species should appear only on the LHS of each reaction (and there should be just one secondary species on the RHS, by definition) so they may have negative coefficients. Each row should have number of primary_concentrations entries, which are the stoichiometric coefficients. The first coefficient must always correspond to the first primary species, etc
C++ Type:std::vector<double>
Unit:(no unit assumed)
Controllable:No
Description:A matrix defining the aqueous reactions. The matrix is entered as a long vector: the first row is entered first, followed by the second row, etc. There should be num_reactions rows. All primary species should appear only on the LHS of each reaction (and there should be just one secondary species on the RHS, by definition) so they may have negative coefficients. Each row should have number of primary_concentrations entries, which are the stoichiometric coefficients. The first coefficient must always correspond to the first primary species, etc
 - specific_reactive_surface_areaSpecific reactive surface area in m^2/(L solution).
C++ Type:std::vector<double>
Unit:(no unit assumed)
Controllable:No
Description:Specific reactive surface area in m^2/(L solution).
 
PorousFlow Aqueous PreDis Chemistry
This Material forms a std::vector of mineralisation reaction rates (L(precipitate)/L(solution)/s) appropriate to the aqueous precipitation-dissolution system provided. Note: the PorousFlowTemperature must be measured in Kelvin.
This computes reaction rates resulting from a precipitation-dissolution (PreDis) kinetic reaction system.
The numerical implementation of the chemical-reactions part of PorousFlow is quite simplistic, with very few guards against strange numerical behavior that might arise during the non-linear iterative process that MOOSE uses to find the solution.  Therefore, care must be taken to define your chemical reactions so that the primary species concentrations remain small, but nonzero, and that mineralisation doesn't cause porosity to become negative or exceed unity.
Details concerning precipitation-dissolution kinetic chemistry may be found in the chemical reactions module.  There are two main differences between the chemical reactions module and PorousFlow.  These are:
The molar volumes must be specified in
PorousFlow. This is so that the concentrations may be measured in rather than mol.m.Unlike the
chemical reactionsmodule, users ofPorousFlowmust specify the stoichiometric coefficients themselves. In each reaction, the primary concentrations (variables) must be brought to the left-hand-side. The right-hand-sides are the minerals, by definition. For instance, consider a 2-reaction system consisting of 3 primary variables, , and . The reactions areThen the
reactionsinput is1 2 -3 4 -5 6.
If the equilibrium constants are AuxVariables that depend on temperature (or other Variables) the computed Jacobian will not be exact and you may experience poor nonlinear convergence. If this becomes frustrating, please contact the MOOSE Discussion forum.
Input Parameters
- at_nodesFalseEvaluate Material properties at nodes instead of quadpoints
Default:False
C++ Type:bool
Controllable:No
Description:Evaluate Material properties at nodes instead of quadpoints
 - blockThe list of blocks (ids or names) that this object will be applied
C++ Type:std::vector<SubdomainName>
Controllable:No
Description:The list of blocks (ids or names) that this object will be applied
 - boundaryThe list of boundaries (ids or names) from the mesh where this object applies
C++ Type:std::vector<BoundaryName>
Controllable:No
Description:The list of boundaries (ids or names) from the mesh where this object applies
 - computeTrueWhen false, MOOSE will not call compute methods on this material. The user must call computeProperties() after retrieving the MaterialBase via MaterialBasePropertyInterface::getMaterialBase(). Non-computed MaterialBases are not sorted for dependencies.
Default:True
C++ Type:bool
Controllable:No
Description:When false, MOOSE will not call compute methods on this material. The user must call computeProperties() after retrieving the MaterialBase via MaterialBasePropertyInterface::getMaterialBase(). Non-computed MaterialBases are not sorted for dependencies.
 - constant_onNONEWhen ELEMENT, MOOSE will only call computeQpProperties() for the 0th quadrature point, and then copy that value to the other qps.When SUBDOMAIN, MOOSE will only call computeQpProperties() for the 0th quadrature point, and then copy that value to the other qps. Evaluations on element qps will be skipped
Default:NONE
C++ Type:MooseEnum
Options:NONE, ELEMENT, SUBDOMAIN
Controllable:No
Description:When ELEMENT, MOOSE will only call computeQpProperties() for the 0th quadrature point, and then copy that value to the other qps.When SUBDOMAIN, MOOSE will only call computeQpProperties() for the 0th quadrature point, and then copy that value to the other qps. Evaluations on element qps will be skipped
 - declare_suffixAn optional suffix parameter that can be appended to any declared properties. The suffix will be prepended with a '_' character.
C++ Type:MaterialPropertyName
Unit:(no unit assumed)
Controllable:No
Description:An optional suffix parameter that can be appended to any declared properties. The suffix will be prepended with a '_' character.
 - equilibrium_constants_as_log10FalseIf true, the equilibrium constants are written in their log10 form, eg, -2. If false, the equilibrium constants are written in absolute terms, eg, 0.01
Default:False
C++ Type:bool
Controllable:No
Description:If true, the equilibrium constants are written in their log10 form, eg, -2. If false, the equilibrium constants are written in absolute terms, eg, 0.01
 - eta_exponentEta exponent. Defaults to 1. (one for each reaction)
C++ Type:std::vector<double>
Unit:(no unit assumed)
Controllable:No
Description:Eta exponent. Defaults to 1. (one for each reaction)
 - gas_constant8.31434Gas constant, in J/(mol K)
Default:8.31434
C++ Type:double
Unit:(no unit assumed)
Controllable:No
Description:Gas constant, in J/(mol K)
 - reference_temperature298.15Reference temperature, K
Default:298.15
C++ Type:double
Unit:(no unit assumed)
Controllable:No
Description:Reference temperature, K
 - theta_exponentTheta exponent. Defaults to 1. (one for each reaction)
C++ Type:std::vector<double>
Unit:(no unit assumed)
Controllable:No
Description:Theta exponent. Defaults to 1. (one for each reaction)
 
Optional Parameters
- control_tagsAdds user-defined labels for accessing object parameters via control logic.
C++ Type:std::vector<std::string>
Controllable:No
Description:Adds user-defined labels for accessing object parameters via control logic.
 - enableTrueSet the enabled status of the MooseObject.
Default:True
C++ Type:bool
Controllable:Yes
Description:Set the enabled status of the MooseObject.
 - implicitTrueDetermines whether this object is calculated using an implicit or explicit form
Default:True
C++ Type:bool
Controllable:No
Description:Determines whether this object is calculated using an implicit or explicit form
 - search_methodnearest_node_connected_sidesChoice of search algorithm. All options begin by finding the nearest node in the primary boundary to a query point in the secondary boundary. In the default nearest_node_connected_sides algorithm, primary boundary elements are searched iff that nearest node is one of their nodes. This is fast to determine via a pregenerated node-to-elem map and is robust on conforming meshes. In the optional all_proximate_sides algorithm, primary boundary elements are searched iff they touch that nearest node, even if they are not topologically connected to it. This is more CPU-intensive but is necessary for robustness on any boundary surfaces which has disconnections (such as Flex IGA meshes) or non-conformity (such as hanging nodes in adaptively h-refined meshes).
Default:nearest_node_connected_sides
C++ Type:MooseEnum
Options:nearest_node_connected_sides, all_proximate_sides
Controllable:No
Description:Choice of search algorithm. All options begin by finding the nearest node in the primary boundary to a query point in the secondary boundary. In the default nearest_node_connected_sides algorithm, primary boundary elements are searched iff that nearest node is one of their nodes. This is fast to determine via a pregenerated node-to-elem map and is robust on conforming meshes. In the optional all_proximate_sides algorithm, primary boundary elements are searched iff they touch that nearest node, even if they are not topologically connected to it. This is more CPU-intensive but is necessary for robustness on any boundary surfaces which has disconnections (such as Flex IGA meshes) or non-conformity (such as hanging nodes in adaptively h-refined meshes).
 - seed0The seed for the master random number generator
Default:0
C++ Type:unsigned int
Controllable:No
Description:The seed for the master random number generator
 - 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
Controllable:No
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
- output_propertiesList of material properties, from this material, to output (outputs must also be defined to an output type)
C++ Type:std::vector<std::string>
Controllable:No
Description:List of material properties, from this material, to output (outputs must also be defined to an output type)
 - outputsnone Vector of output names where you would like to restrict the output of variables(s) associated with this object
Default:none
C++ Type:std::vector<OutputName>
Controllable:No
Description:Vector of output names where you would like to restrict the output of variables(s) associated with this object
 
Outputs Parameters
- prop_getter_suffixAn optional suffix parameter that can be appended to any attempt to retrieve/get material properties. The suffix will be prepended with a '_' character.
C++ Type:MaterialPropertyName
Unit:(no unit assumed)
Controllable:No
Description:An optional suffix parameter that can be appended to any attempt to retrieve/get material properties. The suffix will be prepended with a '_' character.
 - use_interpolated_stateFalseFor the old and older state use projected material properties interpolated at the quadrature points. To set up projection use the ProjectedStatefulMaterialStorageAction.
Default:False
C++ Type:bool
Controllable:No
Description:For the old and older state use projected material properties interpolated at the quadrature points. To set up projection use the ProjectedStatefulMaterialStorageAction.
 
Material Property Retrieval Parameters
Input Files
- (modules/porous_flow/test/tests/chemistry/except13.i)
 - (modules/porous_flow/test/tests/jacobian/chem03.i)
 - (modules/porous_flow/examples/thm_example/2D_c.i)
 - (modules/porous_flow/test/tests/chemistry/except8.i)
 - (modules/porous_flow/test/tests/chemistry/dissolution_limited.i)
 - (modules/porous_flow/test/tests/chemistry/except20.i)
 - (modules/porous_flow/test/tests/chemistry/dissolution_limited_2phase.i)
 - (modules/porous_flow/test/tests/chemistry/except9.i)
 - (modules/porous_flow/test/tests/jacobian/chem07.i)
 - (modules/porous_flow/test/tests/chemistry/except22.i)
 - (modules/porous_flow/test/tests/chemistry/except16.i)
 - (modules/porous_flow/test/tests/jacobian/chem01.i)
 - (modules/porous_flow/test/tests/chemistry/except18.i)
 - (modules/porous_flow/test/tests/jacobian/chem10.i)
 - (modules/porous_flow/test/tests/chemistry/except19.i)
 - (modules/porous_flow/test/tests/jacobian/chem11.i)
 - (modules/porous_flow/test/tests/chemistry/except11.i)
 - (modules/porous_flow/test/tests/chemistry/precipitation_porosity_change.i)
 - (modules/porous_flow/test/tests/chemistry/precipitation_2phase.i)
 - (modules/porous_flow/test/tests/chemistry/precipitation.i)
 - (modules/porous_flow/test/tests/chemistry/except14.i)
 - (modules/porous_flow/test/tests/jacobian/chem14.i)
 - (modules/porous_flow/examples/tutorial/13.i)
 - (modules/porous_flow/test/tests/chemistry/except10.i)
 - (modules/porous_flow/test/tests/jacobian/chem06.i)
 - (modules/porous_flow/test/tests/jacobian/chem13.i)
 - (modules/porous_flow/test/tests/jacobian/chem09.i)
 - (modules/porous_flow/test/tests/jacobian/chem12.i)
 - (modules/porous_flow/test/tests/jacobian/chem05.i)
 - (modules/porous_flow/examples/tutorial/07.i)
 - (modules/porous_flow/test/tests/chemistry/except15.i)
 - (modules/porous_flow/test/tests/jacobian/chem08.i)
 - (modules/porous_flow/test/tests/chemistry/2species_predis.i)
 - (modules/porous_flow/test/tests/jacobian/chem04.i)
 - (modules/porous_flow/test/tests/chemistry/dissolution.i)
 - (modules/porous_flow/test/tests/chemistry/except12.i)
 - (modules/porous_flow/test/tests/jacobian/chem02.i)
 
(modules/porous_flow/test/tests/chemistry/except13.i)
# Exception test.
# Incorrect number of eta exponents
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = Diffusion
    variable = a
  []
  [b]
    type = Diffusion
    variable = b
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '1 1'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = 1.0e-8
    activation_energy = 1.5e4
    molar_volume = 1
    eta_exponent = '1 1'
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/jacobian/chem03.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with temperature
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.1
  []
  [b]
    initial_condition = 0.2
  []
  [temp]
    initial_condition = 0.5
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E-5
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E-5
    stoichiometry = 3
  []
  [temp]
    type = Diffusion
    variable = temp
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b temp'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '0.5 0.8'
    reactions = '2 3'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1.1
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/examples/thm_example/2D_c.i)
# Two phase, temperature-dependent, with mechanics and chemistry, radial with fine mesh, constant injection of cold co2 into a overburden-reservoir-underburden containing mostly water
# species=0 is water
# species=1 is co2
# phase=0 is liquid, and since massfrac_ph0_sp0 = 1, this is all water
# phase=1 is gas, and since massfrac_ph1_sp0 = 0, this is all co2
#
# The mesh used below has very high resolution, so the simulation takes a long time to complete.
# Some suggested meshes of different resolution:
# nx=50, bias_x=1.2
# nx=100, bias_x=1.1
# nx=200, bias_x=1.05
# nx=400, bias_x=1.02
# nx=1000, bias_x=1.01
# nx=2000, bias_x=1.003
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 2000
  bias_x = 1.003
  xmin = 0.1
  xmax = 5000
  ny = 1
  ymin = 0
  ymax = 11
  coord_type = RZ
[]
[GlobalParams]
  displacements = 'disp_r disp_z'
  PorousFlowDictator = dictator
  gravity = '0 0 0'
  biot_coefficient = 1.0
[]
[Variables]
  [pwater]
    initial_condition = 18.3e6
  []
  [sgas]
    initial_condition = 0.0
  []
  [temp]
    initial_condition = 358
  []
  [disp_r]
  []
[]
[AuxVariables]
  [rate]
  []
  [disp_z]
  []
  [massfrac_ph0_sp0]
    initial_condition = 1 # all H20 in phase=0
  []
  [massfrac_ph1_sp0]
    initial_condition = 0 # no H2O in phase=1
  []
  [pgas]
    family = MONOMIAL
    order = FIRST
  []
  [swater]
    family = MONOMIAL
    order = FIRST
  []
  [stress_rr]
    order = CONSTANT
    family = MONOMIAL
  []
  [stress_tt]
    order = CONSTANT
    family = MONOMIAL
  []
  [stress_zz]
    order = CONSTANT
    family = MONOMIAL
  []
  [mineral_conc_m3_per_m3]
    family = MONOMIAL
    order = CONSTANT
    initial_condition = 0.1
  []
  [eqm_const]
    initial_condition = 0.0
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[Kernels]
  [mass_water_dot]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pwater
  []
  [flux_water]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    use_displaced_mesh = false
    variable = pwater
  []
  [mass_co2_dot]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = sgas
  []
  [flux_co2]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    use_displaced_mesh = false
    variable = sgas
  []
  [energy_dot]
    type = PorousFlowEnergyTimeDerivative
    variable = temp
  []
  [advection]
    type = PorousFlowHeatAdvection
    use_displaced_mesh = false
    variable = temp
  []
  [conduction]
    type = PorousFlowExponentialDecay
    use_displaced_mesh = false
    variable = temp
    reference = 358
    rate = rate
  []
  [grad_stress_r]
    type = StressDivergenceRZTensors
    temperature = temp
    eigenstrain_names = thermal_contribution
    variable = disp_r
    use_displaced_mesh = false
    component = 0
  []
  [poro_r]
    type = PorousFlowEffectiveStressCoupling
    variable = disp_r
    use_displaced_mesh = false
    component = 0
  []
[]
[AuxKernels]
  [rate]
    type = FunctionAux
    variable = rate
    execute_on = timestep_begin
    function = decay_rate
  []
  [pgas]
    type = PorousFlowPropertyAux
    property = pressure
    phase = 1
    variable = pgas
  []
  [swater]
    type = PorousFlowPropertyAux
    property = saturation
    phase = 0
    variable = swater
  []
  [stress_rr]
    type = RankTwoAux
    rank_two_tensor = stress
    variable = stress_rr
    index_i = 0
    index_j = 0
  []
  [stress_tt]
    type = RankTwoAux
    rank_two_tensor = stress
    variable = stress_tt
    index_i = 2
    index_j = 2
  []
  [stress_zz]
    type = RankTwoAux
    rank_two_tensor = stress
    variable = stress_zz
    index_i = 1
    index_j = 1
  []
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral_conc_m3_per_m3
  []
  [eqm_const_auxk]
    type = ParsedAux
    variable = eqm_const
    coupled_variables = temp
    expression = '(358 - temp) / (358 - 294)'
  []
  [porosity_auxk]
    type = PorousFlowPropertyAux
    property = porosity
    variable = porosity
  []
[]
[Functions]
  [decay_rate]
# Eqn(26) of the first paper of LaForce et al.
# Ka * (rho C)_a = 10056886.914
# h = 11
    type = ParsedFunction
    expression = 'sqrt(10056886.914/t)/11.0'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'temp pwater sgas disp_r'
    number_fluid_phases = 2
    number_fluid_components = 2
    number_aqueous_kinetic = 1
    aqueous_phase_number = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureConst
    pc = 0
  []
[]
[FluidProperties]
  [water]
    type = SimpleFluidProperties
    bulk_modulus = 2.27e14
    density0 = 970.0
    viscosity = 0.3394e-3
    cv = 4149.0
    cp = 4149.0
    porepressure_coefficient = 0.0
    thermal_expansion = 0
  []
  [co2]
    type = SimpleFluidProperties
    bulk_modulus = 2.27e14
    density0 = 516.48
    viscosity = 0.0393e-3
    cv = 2920.5
    cp = 2920.5
    porepressure_coefficient = 0.0
    thermal_expansion = 0
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow2PhasePS
    phase0_porepressure = pwater
    phase1_saturation = sgas
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'massfrac_ph0_sp0 massfrac_ph1_sp0'
  []
  [water]
    type = PorousFlowSingleComponentFluid
    fp = water
    phase = 0
  []
  [gas]
    type = PorousFlowSingleComponentFluid
    fp = co2
    phase = 1
  []
  [porosity_reservoir]
    type = PorousFlowPorosity
    porosity_zero = 0.2
    chemical = true
    reference_chemistry = 0.1
    initial_mineral_concentrations = 0.1
  []
  [permeability_reservoir]
    type = PorousFlowPermeabilityConst
    permeability = '2e-12 0 0  0 0 0  0 0 0'
  []
  [relperm_liquid]
    type = PorousFlowRelativePermeabilityCorey
    n = 4
    phase = 0
    s_res = 0.200
    sum_s_res = 0.405
  []
  [relperm_gas]
    type = PorousFlowRelativePermeabilityBC
    phase = 1
    s_res = 0.205
    sum_s_res = 0.405
    nw_phase = true
    lambda = 2
  []
  [thermal_conductivity_reservoir]
    type = PorousFlowThermalConductivityIdeal
    dry_thermal_conductivity = '0 0 0  0 1.320 0  0 0 0'
    wet_thermal_conductivity = '0 0 0  0 3.083 0  0 0 0'
  []
  [internal_energy_reservoir]
    type = PorousFlowMatrixInternalEnergy
    specific_heat_capacity = 1100
    density = 2350.0
  []
  [elasticity_tensor]
    type = ComputeIsotropicElasticityTensor
    shear_modulus = 6.0E9
    poissons_ratio = 0.2
  []
  [strain]
    type = ComputeAxisymmetricRZSmallStrain
    eigenstrain_names = 'thermal_contribution ini_stress'
  []
  [ini_strain]
    type = ComputeEigenstrainFromInitialStress
    initial_stress = '-12.8E6 0 0  0 -51.3E6 0  0 0 -12.8E6'
    eigenstrain_name = ini_stress
  []
  [thermal_contribution]
    type = ComputeThermalExpansionEigenstrain
    temperature = temp
    stress_free_temperature = 358
    thermal_expansion_coeff = 5E-6
    eigenstrain_name = thermal_contribution
  []
  [stress]
    type = ComputeLinearElasticStress
  []
  [eff_fluid_pressure]
    type = PorousFlowEffectiveFluidPressure
  []
  [vol_strain]
    type = PorousFlowVolumetricStrain
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    num_reactions = 1
    primary_concentrations = 1.0 # fixed activity
    equilibrium_constants_as_log10 = true
    equilibrium_constants = eqm_const
    primary_activity_coefficients = 1.0 # fixed activity
    reactions = 1
    kinetic_rate_constant = 1E-6
    molar_volume = 1.0
    specific_reactive_surface_area = 1.0
    activation_energy = 0.0 # no Arrhenius
  []
  [mineral_conc]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = 0.1
  []
  [predis_nodes]
    type = PorousFlowAqueousPreDisChemistry
    at_nodes = true
    num_reactions = 1
    primary_concentrations = 1.0 # fixed activity
    equilibrium_constants_as_log10 = true
    equilibrium_constants = eqm_const
    primary_activity_coefficients = 1.0 # fixed activity
    reactions = 1
    kinetic_rate_constant = 1E-6
    molar_volume = 1.0
    specific_reactive_surface_area = 1.0
    activation_energy = 0.0 # no Arrhenius
  []
  [mineral_conc_nodes]
    type = PorousFlowAqueousPreDisMineral
    at_nodes = true
    initial_concentrations = 0.1
  []
[]
[BCs]
  [outer_pressure_fixed]
    type = DirichletBC
    boundary = right
    value = 18.3e6
    variable = pwater
  []
  [outer_saturation_fixed]
    type = DirichletBC
    boundary = right
    value = 0.0
    variable = sgas
  []
  [outer_temp_fixed]
    type = DirichletBC
    boundary = right
    value = 358
    variable = temp
  []
  [fixed_outer_r]
    type = DirichletBC
    variable = disp_r
    value = 0
    boundary = right
  []
  [co2_injection]
    type = PorousFlowSink
    boundary = left
    variable = sgas
    use_mobility = false
    use_relperm = false
    fluid_phase = 1
    flux_function = 'min(t/100.0,1)*(-2.294001475)' # 5.0E5 T/year = 15.855 kg/s, over area of 2Pi*0.1*11
  []
  [cold_co2]
    type = DirichletBC
    boundary = left
    variable = temp
    value = 294
  []
  [cavity_pressure_x]
    type = Pressure
    boundary = left
    variable = disp_r
    component = 0
    postprocessor = p_bh # note, this lags
    use_displaced_mesh = false
  []
[]
[Postprocessors]
  [p_bh]
    type = PointValue
    variable = pwater
    point = '0.1 0 0'
    execute_on = timestep_begin
    use_displaced_mesh = false
  []
  [mineral_bh] # mineral concentration (m^3(mineral)/m^3(rock)) at the borehole
    type = PointValue
    variable = mineral_conc_m3_per_m3
    point = '0.1 0 0'
    use_displaced_mesh = false
  []
[]
[VectorPostprocessors]
  [ptsuss]
    type = LineValueSampler
    use_displaced_mesh = false
    start_point = '0.1 0 0'
    end_point = '5000 0 0'
    sort_by = x
    num_points = 50000
    outputs = csv
    variable = 'pwater temp sgas disp_r stress_rr stress_tt mineral_conc_m3_per_m3 porosity'
  []
[]
[Preconditioning]
  active = 'smp'
  [smp]
    type = SMP
    full = true
    #petsc_options = '-snes_converged_reason -ksp_diagonal_scale -ksp_diagonal_scale_fix -ksp_gmres_modifiedgramschmidt -snes_linesearch_monitor'
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap -snes_atol -snes_rtol -snes_max_it'
    petsc_options_value = 'gmres      asm      lu           NONZERO                   2               1E2       1E-5        50'
  []
  [mumps]
    type = SMP
    full = true
    petsc_options = '-snes_converged_reason -ksp_diagonal_scale -ksp_diagonal_scale_fix -ksp_gmres_modifiedgramschmidt -snes_linesearch_monitor'
    petsc_options_iname = '-ksp_type -pc_type -pc_factor_mat_solver_package -pc_factor_shift_type -snes_rtol -snes_atol -snes_max_it'
    petsc_options_value = 'gmres      lu       mumps                         NONZERO               1E-5       1E2       50'
  []
[]
[Executioner]
  type = Transient
  solve_type = NEWTON
  end_time = 1.5768e8
  #dtmax = 1e6
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1
    growth_factor = 1.1
  []
[]
[Outputs]
  print_linear_residuals = false
  sync_times = '3600 86400 2.592E6 1.5768E8'
  perf_graph = true
  exodus = true
  [csv]
    type = CSV
    sync_only = true
  []
[]
(modules/porous_flow/test/tests/chemistry/except8.i)
# Exception test.
# Incorrect number of reactive surface areas
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = Diffusion
    variable = a
  []
  [b]
    type = Diffusion
    variable = b
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '1 1'
    specific_reactive_surface_area = '1.0 1.0'
    kinetic_rate_constant = '1.0e-8'
    activation_energy = '1.5e4'
    molar_volume = 1
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/chemistry/dissolution_limited.i)
# The dissolution reaction, with limited initial mineral concentration
#
# a <==> mineral
#
# produces "mineral".  Using mineral_density = fluid_density, theta = 1 = eta, the DE is
#
# a' = -(mineral / porosity)' = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#
# The following parameters are used
#
# T_ref = 0.5 K
# T = 1 K
# activation_energy = 3 J/mol
# gas_constant = 6 J/(mol K)
# kinetic_rate_at_ref_T = 0.60653 mol/(m^2 s)
# These give rate = 0.60653 * exp(1/2) = 1 mol/(m^2 s)
#
# surf_area = 0.5 m^2/L
# molar_volume = 2 L/mol
# These give rate * surf_area * molar_vol = 1 s^-1
#
# equilibrium_constant = 0.5 (dimensionless)
# primary_activity_coefficient = 2 (dimensionless)
# stoichiometry = 1 (dimensionless)
# This means that 1 - (1 / eqm_const) * (act_coeff * a)^stoi = 1 - 4 a, which is positive for a < 0.25, ie dissolution for a(t=0) < 0.25
#
# The solution of the DE is
# a = eqm_const / act_coeff + (a(t=0) - eqm_const / act_coeff) exp(-rate * surf_area * molar_vol * act_coeff * t / eqm_const)
#   = 0.25 + (a(t=0) - 0.25) exp(-4 * t)
# c = c(t=0) - (a - a(t=0)) * porosity
#
# However, c(t=0) is small, so that the reaction only works until c=0, then a and c both remain fixed
#
# This test checks that (a + c / porosity) is time-independent, and that a follows the above solution, until c=0 and thereafter remains fixed.
#
# Aside:
#    The exponential curve is not followed exactly because moose actually solves
#    (a - a_old)/dt = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#    which does not give an exponential exactly, except in the limit dt->0
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.05
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 0.5
  []
  [pressure]
  []
  [ini_mineral_conc]
    initial_condition = 0.015
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [should_be_static]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [should_be_static]
    type = ParsedAux
    coupled_variables = 'mineral a'
    expression = 'a + mineral / 0.1'
    variable = should_be_static
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [mass_a]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = a
  []
  [pre_dis]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1000
    stoichiometry = 1
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = a
    number_fluid_phases = 1
    number_fluid_components = 2
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e9 # huge, so mimic chemical_reactions
    density0 = 1000
    thermal_expansion = 0
    viscosity = 1e-3
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 1
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [mass_frac]
    type = PorousFlowMassFraction
    mass_fraction_vars = a
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.01
  end_time = 1
[]
[Postprocessors]
  [a]
    type = PointValue
    point = '0 0 0'
    variable = a
  []
  [should_be_static]
    type = PointValue
    point = '0 0 0'
    variable = should_be_static
  []
[]
[Outputs]
  time_step_interval = 10
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/chemistry/except20.i)
# Exception test
# No reference chemistry
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [dummy]
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [a]
    initial_condition = 0.5
  []
  [ini_mineral_conc]
    initial_condition = 0.2
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [porosity]
    type = PorousFlowPropertyAux
    property = porosity
    variable = porosity
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [dummy]
    type = Diffusion
    variable = dummy
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = dummy
    number_fluid_phases = 1
    number_fluid_components = 2
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[Materials]
  [temperature_qp]
    type = PorousFlowTemperature
    temperature = 1
  []
  [predis_qp]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc_qp]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [porosity]
    type = PorousFlowPorosity
    chemical = true
    porosity_zero = 0.6
    initial_mineral_concentrations = ini_mineral_conc
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.1
  end_time = 0.4
[]
[Postprocessors]
  [porosity]
    type = PointValue
    point = '0 0 0'
    variable = porosity
  []
  [c]
    type = PointValue
    point = '0 0 0'
    variable = mineral
  []
[]
[Outputs]
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/chemistry/dissolution_limited_2phase.i)
# Using a two-phase system (see dissolution_limited.i for the single-phase)
# The saturation and porosity are chosen so that the results are identical to dissolution_limited.i
#
# The dissolution reaction, with limited initial mineral concentration
#
# a <==> mineral
#
# produces "mineral".  Using mineral_density = fluid_density, theta = 1 = eta, the DE is
#
# a' = -(mineral / (porosity * saturation))' = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#
# The following parameters are used
#
# T_ref = 0.5 K
# T = 1 K
# activation_energy = 3 J/mol
# gas_constant = 6 J/(mol K)
# kinetic_rate_at_ref_T = 0.60653 mol/(m^2 s)
# These give rate = 0.60653 * exp(1/2) = 1 mol/(m^2 s)
#
# surf_area = 0.5 m^2/L
# molar_volume = 2 L/mol
# These give rate * surf_area * molar_vol = 1 s^-1
#
# equilibrium_constant = 0.5 (dimensionless)
# primary_activity_coefficient = 2 (dimensionless)
# stoichiometry = 1 (dimensionless)
# This means that 1 - (1 / eqm_const) * (act_coeff * a)^stoi = 1 - 4 a, which is positive for a < 0.25, ie dissolution for a(t=0) < 0.25
#
# The solution of the DE is
# a = eqm_const / act_coeff + (a(t=0) - eqm_const / act_coeff) exp(-rate * surf_area * molar_vol * act_coeff * t / eqm_const)
#   = 0.25 + (a(t=0) - 0.25) exp(-4 * t)
# c = c(t=0) - (a - a(t=0)) * porosity * saturation
#
# However, c(t=0) is small, so that the reaction only works until c=0, then a and c both remain fixed
#
# This test checks that (a + c / (porosity * saturation)) is time-independent, and that a follows the above solution, until c=0 and thereafter remains fixed.
#
# Aside:
#    The exponential curve is not followed exactly because moose actually solves
#    (a - a_old)/dt = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#    which does not give an exponential exactly, except in the limit dt->0
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.05
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 0.5
  []
  [pressure0]
  []
  [saturation1]
    initial_condition = 0.25
  []
  [b]
    initial_condition = 0.123
  []
  [ini_mineral_conc]
    initial_condition = 0.015
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [should_be_static]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [should_be_static]
    type = ParsedAux
    coupled_variables = 'mineral a'
    expression = 'a + mineral / 0.1'
    variable = should_be_static
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [mass_a]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = a
  []
  [pre_dis]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1000
    stoichiometry = 1
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = a
    number_fluid_phases = 2
    number_fluid_components = 2
    number_aqueous_kinetic = 1
    aqueous_phase_number = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureConst
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e9 # huge, so mimic chemical_reactions
    density0 = 1000
    thermal_expansion = 0
    viscosity = 1e-3
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 1
  []
  [ppss]
    type = PorousFlow2PhasePS
    capillary_pressure = pc
    phase0_porepressure = pressure0
    phase1_saturation = saturation1
  []
  [mass_frac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'b a'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [simple_fluid0]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [simple_fluid1]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.4
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.01
  end_time = 1
[]
[Postprocessors]
  [a]
    type = PointValue
    point = '0 0 0'
    variable = a
  []
  [should_be_static]
    type = PointValue
    point = '0 0 0'
    variable = should_be_static
  []
[]
[Outputs]
  time_step_interval = 10
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/chemistry/except9.i)
# Exception test.
# Incorrect number of kinetic rate constants
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = Diffusion
    variable = a
  []
  [b]
    type = Diffusion
    variable = b
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '1 1'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = '1.0e-8 1'
    activation_energy = '1.5e4'
    molar_volume = 1
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/jacobian/chem07.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with no temperature dependence, with two primary variables = 0
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.0
  []
  [b]
    initial_condition = 0.0
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [temp]
    initial_condition = 0.5
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E5
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E5
    stoichiometry = 3
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '0.5 0.8'
    reactions = '1 3'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1.0
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/chemistry/except22.i)
# Exception test
# Zero fluid phases
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [dummy]
  []
[]
[AuxVariables]
  [a]
    initial_condition = 0.5
  []
  [ini_mineral_conc]
    initial_condition = 0.2
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [porosity]
    type = PorousFlowPropertyAux
    property = porosity
    variable = porosity
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [dummy]
    type = Diffusion
    variable = dummy
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = dummy
    number_fluid_phases = 0
    number_fluid_components = 2
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[Materials]
  [temperature_qp]
    type = PorousFlowTemperature
    temperature = 1
  []
  [predis_qp]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = 0.5
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc_qp]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [porosity]
    type = PorousFlowPorosity
    chemical = true
    porosity_zero = 0.6
    reference_chemistry = ini_mineral_conc
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.1
  end_time = 0.4
[]
[Postprocessors]
  [porosity]
    type = PointValue
    point = '0 0 0'
    variable = porosity
  []
  [c]
    type = PointValue
    point = '0 0 0'
    variable = mineral
  []
[]
[Outputs]
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/chemistry/except16.i)
# Exception test
# Incorrect number of stoichiometry
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1
    stoichiometry = '2 3'
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 1
    stoichiometry = 3
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '2 3'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = 1.0e-8
    activation_energy = 1.5e4
    molar_volume = 1
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/jacobian/chem01.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with temperature
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.25
  []
  [b]
    initial_condition = 0.2
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [temp]
    initial_condition = 0.5
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E5
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E5
    stoichiometry = 3
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '0.5 0.8'
    reactions = '2 3'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1.1
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/chemistry/except18.i)
# Exception test
# Incorrect number of kinetic in dictator
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = Diffusion
    variable = a
  []
  [b]
    type = Diffusion
    variable = b
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_equilibrium = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '2 3'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = 1.0e-8
    activation_energy = 1.5e4
    molar_volume = 1
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/jacobian/chem10.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with temperature, with two primary variables = 0
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.0
  []
  [b]
    initial_condition = 0.0
  []
  [temp]
    initial_condition = 0.5
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E5
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E5
    stoichiometry = 3
  []
  [temp]
    type = Diffusion
    variable = temp
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b temp'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '0.5 0.8'
    reactions = '1 3'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1.0
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/chemistry/except19.i)
# Exception test
# No initial_mineral_concentrations
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [dummy]
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 0.5
  []
  [a]
    initial_condition = 0.5
  []
  [ini_mineral_conc]
    initial_condition = 0.2
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [porosity]
    type = PorousFlowPropertyAux
    property = porosity
    variable = porosity
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [dummy]
    type = Diffusion
    variable = dummy
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = dummy
    number_fluid_phases = 1
    number_fluid_components = 2
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[Materials]
  [temperature_qp]
    type = PorousFlowTemperature
    temperature = 1
  []
  [predis_qp]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc_qp]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [porosity]
    type = PorousFlowPorosity
    chemical = true
    porosity_zero = 0.6
    reference_chemistry = ini_mineral_conc
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.1
  end_time = 0.4
[]
[Postprocessors]
  [porosity]
    type = PointValue
    point = '0 0 0'
    variable = porosity
  []
  [c]
    type = PointValue
    point = '0 0 0'
    variable = mineral
  []
[]
[Outputs]
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/jacobian/chem11.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with temperature, with three primary variables and four reactions
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.05
  []
  [b]
    initial_condition = 0.1
  []
  [c]
    initial_condition = 0.15
  []
  [temp]
    initial_condition = 0.5
  []
[]
[AuxVariables]
  [eqm_k0]
    initial_condition = 0.1
  []
  [eqm_k1]
    initial_condition = 0.2
  []
  [eqm_k2]
    initial_condition = -0.2
  []
  [eqm_k3]
    initial_condition = 0.0
  []
  [ini_sec_conc0]
    initial_condition = 0.02
  []
  [ini_sec_conc1]
    initial_condition = 0.04
  []
  [ini_sec_conc2]
    initial_condition = 0.06
  []
  [ini_sec_conc3]
    initial_condition = 0.08
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = '1E10 2E10 3E10 4E10'
    stoichiometry = '1 1 2 0.1'
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = '1.1E10 2.2E10 3.3E10 4.4E10'
    stoichiometry = '2 2 0.1 0.5'
  []
  [c]
    type = PorousFlowPreDis
    variable = c
    mineral_density = '0.1E10 0.2E10 0.3E10 0.4E10'
    stoichiometry = '3 3 0.1 1'
  []
  [temp]
    type = Diffusion
    variable = temp
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b c temp'
    number_fluid_phases = 1
    number_fluid_components = 4
    number_aqueous_kinetic = 4
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b c'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b c'
    num_reactions = 4
    equilibrium_constants_as_log10 = true
    equilibrium_constants = 'eqm_k0 eqm_k1 eqm_k2 eqm_k3'
    primary_activity_coefficients = '0.5 0.8 0.9'
    reactions = '1 2 3
                 1 -2 -3
                 2 0.1 0.1
                 0.1 0.5 1'
    specific_reactive_surface_area = '-44.4E-2 22.1E-2 32.1E-1 -50E-2'
    kinetic_rate_constant = '0.678 0.999 1.23 0.3'
    activation_energy = '4.4 3.3 4.5 4.0'
    molar_volume = '3.3 4.4 5.5 6.6'
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = '1.0 1.1 1.2 0.9'
    eta_exponent = '1.2 1.01 1.1 1.2'
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = 'ini_sec_conc0 ini_sec_conc1 ini_sec_conc2 ini_sec_conc3'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/chemistry/except11.i)
# Exception test.
# Incorrect number of molar volumes
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = Diffusion
    variable = a
  []
  [b]
    type = Diffusion
    variable = b
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '1 1'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = 1.0e-8
    activation_energy = 1.5e4
    molar_volume = '1 1'
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/chemistry/precipitation_porosity_change.i)
# Test to illustrate porosity evolution due to precipitation
#
# The precipitation reaction
#
# a <==> mineral
#
# produces "mineral".  Using theta = 1 = eta, the DE that describes the prcipitation is
# reaction_rate = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#
# The following parameters are used
#
# T_ref = 0.5 K
# T = 1 K
# activation_energy = 3 J/mol
# gas_constant = 6 J/(mol K)
# kinetic_rate_at_ref_T = 0.60653 mol/(m^2 s)
# These give rate = 0.60653 * exp(1/2) = 1 mol/(m^2 s)
#
# surf_area = 0.5 m^2/L
# molar_volume = 2 L/mol
# These give rate * surf_area * molar_vol = 1 s^-1
#
# equilibrium_constant = 0.5 (dimensionless)
# primary_activity_coefficient = 2 (dimensionless)
# stoichiometry = 1 (dimensionless)
# This means that 1 - (1 / eqm_const) * (act_coeff * a)^stoi = 1 - 4 a, which is negative (ie precipitation) for a > 0.25
#
# a is held fixed at 0.5, so
# reaction_rate = - (1 - 2) = 1
#
# The mineral volume fraction evolves according to
# Mineral = mineral_old + dt * porosity_old * reaction_rate = mineral_old + dt * porosity_old
#
# Porosity evolves according to
# porosity = porosity(t=0) - (mineral - mineral(t=0))
#          = porosity(t=0) - (mineral_old + dt * porosity_old * reaction_rate - mineral(t=0))
#
# Specifically:
# time mineral porosity
# 0    0.2     0.6
# 0.1  0.26    0.54
# 0.2  0.314   0.486
# 0.3  0.3626  0.4374
# 0.4  0.40634 0.39366
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [dummy]
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 0.5
  []
  [a]
    initial_condition = 0.5
  []
  [ini_mineral_conc]
    initial_condition = 0.2
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [porosity]
    type = PorousFlowPropertyAux
    property = porosity
    variable = porosity
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [dummy]
    type = Diffusion
    variable = dummy
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = dummy
    number_fluid_phases = 1
    number_fluid_components = 2
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 1
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = dummy
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [porosity]
    type = PorousFlowPorosity
    chemical = true
    porosity_zero = 0.6
    reference_chemistry = ini_mineral_conc
    initial_mineral_concentrations = ini_mineral_conc
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.1
  end_time = 0.4
[]
[Postprocessors]
  [porosity]
    type = PointValue
    point = '0 0 0'
    variable = porosity
  []
  [c]
    type = PointValue
    point = '0 0 0'
    variable = mineral
  []
[]
[Outputs]
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/chemistry/precipitation_2phase.i)
# Using a two-phase system (see precipitation.i for the single-phase)
# The saturation and porosity are chosen so that the results are identical to precipitation.i
#
# The precipitation reaction
#
# a <==> mineral
#
# produces "mineral".  Using mineral_density = fluid_density, theta = 1 = eta, the DE is
#
# a' = -(mineral / (porosity * saturation))' = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#
# The following parameters are used
#
# T_ref = 0.5 K
# T = 1 K
# activation_energy = 3 J/mol
# gas_constant = 6 J/(mol K)
# kinetic_rate_at_ref_T = 0.60653 mol/(m^2 s)
# These give rate = 0.60653 * exp(1/2) = 1 mol/(m^2 s)
#
# surf_area = 0.5 m^2/L
# molar_volume = 2 L/mol
# These give rate * surf_area * molar_vol = 1 s^-1
#
# equilibrium_constant = 0.5 (dimensionless)
# primary_activity_coefficient = 2 (dimensionless)
# stoichiometry = 1 (dimensionless)
# This means that 1 - (1 / eqm_const) * (act_coeff * a)^stoi = 1 - 4 a, which is negative for a > 0.25, ie precipitation for a(t=0) > 0.25
#
# The solution of the DE is
# a = eqm_const / act_coeff + (a(t=0) - eqm_const / act_coeff) exp(-rate * surf_area * molar_vol * act_coeff * t / eqm_const)
#   = 0.25 + (a(t=0) - 0.25) exp(-4 * t)
# c = c(t=0) - (a - a(t=0)) * (porosity * saturation)
#
# This test checks that (a + c / (porosity * saturation)) is time-independent, and that a follows the above solution
#
# Aside:
#    The exponential curve is not followed exactly because moose actually solves
#    (a - a_old)/dt = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#    which does not give an exponential exactly, except in the limit dt->0
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.9
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 0.5
  []
  [pressure0]
  []
  [saturation1]
    initial_condition = 0.25
  []
  [b]
    initial_condition = 0.123
  []
  [ini_mineral_conc]
    initial_condition = 0.2
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [should_be_static]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [should_be_static]
    type = ParsedAux
    coupled_variables = 'mineral a'
    expression = 'a + mineral / 0.1'
    variable = should_be_static
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [mass_a]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = a
  []
  [pre_dis]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1000
    stoichiometry = 1
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = a
    number_fluid_phases = 2
    number_fluid_components = 2
    number_aqueous_kinetic = 1
    aqueous_phase_number = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureConst
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e9 # huge, so mimic chemical_reactions
    density0 = 1000
    thermal_expansion = 0
    viscosity = 1e-3
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 1
  []
  [ppss]
    type = PorousFlow2PhasePS
    capillary_pressure = pc
    phase0_porepressure = pressure0
    phase1_saturation = saturation1
  []
  [mass_frac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'b a'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [simple_fluid0]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [simple_fluid1]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.4
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.01
  end_time = 1
[]
[Postprocessors]
  [a]
    type = PointValue
    point = '0 0 0'
    variable = a
  []
  [should_be_static]
    type = PointValue
    point = '0 0 0'
    variable = should_be_static
  []
[]
[Outputs]
  time_step_interval = 10
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/chemistry/precipitation.i)
# The precipitation reaction
#
# a <==> mineral
#
# produces "mineral".  Using mineral_density = fluid_density, theta = 1 = eta, the DE is
#
# a' = -(mineral / porosity)' = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#
# The following parameters are used
#
# T_ref = 0.5 K
# T = 1 K
# activation_energy = 3 J/mol
# gas_constant = 6 J/(mol K)
# kinetic_rate_at_ref_T = 0.60653 mol/(m^2 s)
# These give rate = 0.60653 * exp(1/2) = 1 mol/(m^2 s)
#
# surf_area = 0.5 m^2/L
# molar_volume = 2 L/mol
# These give rate * surf_area * molar_vol = 1 s^-1
#
# equilibrium_constant = 0.5 (dimensionless)
# primary_activity_coefficient = 2 (dimensionless)
# stoichiometry = 1 (dimensionless)
# This means that 1 - (1 / eqm_const) * (act_coeff * a)^stoi = 1 - 4 a, which is negative for a > 0.25, ie precipitation for a(t=0) > 0.25
#
# The solution of the DE is
# a = eqm_const / act_coeff + (a(t=0) - eqm_const / act_coeff) exp(-rate * surf_area * molar_vol * act_coeff * t / eqm_const)
#   = 0.25 + (a(t=0) - 0.25) exp(-4 * t)
# c = c(t=0) - (a - a(t=0)) * porosity
#
# This test checks that (a + c / porosity) is time-independent, and that a follows the above solution
#
# Aside:
#    The exponential curve is not followed exactly because moose actually solves
#    (a - a_old)/dt = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#    which does not give an exponential exactly, except in the limit dt->0
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.9
  []
[]
[AuxVariables]
  [pressure]
  []
  [ini_mineral_conc]
    initial_condition = 0.2
  []
  [k]
    initial_condition = 0.5
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [should_be_static]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [should_be_static]
    type = ParsedAux
    coupled_variables = 'mineral a'
    expression = 'a + mineral / 0.1'
    variable = should_be_static
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [mass_a]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = a
  []
  [pre_dis]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1000
    stoichiometry = 1
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = a
    number_fluid_phases = 1
    number_fluid_components = 2
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e9 # huge, so mimic chemical_reactions
    density0 = 1000
    thermal_expansion = 0
    viscosity = 1e-3
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 1
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [mass_frac]
    type = PorousFlowMassFraction
    mass_fraction_vars = a
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = k
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.01
  end_time = 1
[]
[Postprocessors]
  [a]
    type = PointValue
    point = '0 0 0'
    variable = a
  []
  [should_be_static]
    type = PointValue
    point = '0 0 0'
    variable = should_be_static
  []
[]
[Outputs]
  time_step_interval = 10
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/chemistry/except14.i)
# Exception test.
# Incorrect number of initial concentrations
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = Diffusion
    variable = a
  []
  [b]
    type = Diffusion
    variable = b
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [ini_conc_0]
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '1 1'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = 1.0e-8
    activation_energy = 1.5e4
    molar_volume = 1
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = 'ini_conc_0 ini_conc_0'
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/jacobian/chem14.i)
# Check derivatives of PorousFlowPorosity with chemical=true
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.1
  []
[]
[AuxVariables]
  [eqm_k0]
    initial_condition = 1.234
  []
  [eqm_k1]
    initial_condition = 0.987
  []
  [temp]
    initial_condition = 0.5
  []
  [ini_sec_conc0]
    initial_condition = 0.111
  []
  [ini_sec_conc1]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowMassTimeDerivative # this is rather irrelevant: we just want something with Porosity in it
    variable = a
    fluid_component = 0
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = a
    number_fluid_phases = 1
    number_fluid_components = 2
    number_aqueous_kinetic = 2
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
    at_nodes = true
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    at_nodes = true
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = a
    at_nodes = true
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 2
    equilibrium_constants = 'eqm_k0 eqm_k1'
    primary_activity_coefficients = 1
    reactions = '1E-10
                 2E-10'  # so that mass_frac = a
    specific_reactive_surface_area = '-44.4E-2 -12E-2'
    kinetic_rate_constant = '0.678 0.7'
    activation_energy = '4.4 3.3'
    molar_volume = '3.3 2.2'
    reference_temperature = 1
    gas_constant = 7.4
    at_nodes = true
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = 'ini_sec_conc0 ini_sec_conc1'
    at_nodes = true
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    at_nodes = true
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosity
    chemical = true
    porosity_zero = 0.1
    reference_chemistry = 'ini_sec_conc0 ini_sec_conc1'
    initial_mineral_concentrations = 'ini_sec_conc0 ini_sec_conc1'
    chemical_weights = '1.111 0.888' # so derivatives of porosity are big
    at_nodes = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/examples/tutorial/13.i)
# Example of reactive transport model with dissolution of dolomite
#
# The equilibrium system has 5 primary species (Variables) and
# 5 secondary species (PorousFlowMassFractionAqueousEquilibrium).
# Some of the equilibrium constants have been chosen rather arbitrarily.
#
# Equilibrium reactions
# H+  + HCO3-                      = CO2(aq)
# -H+ + HCO3-                      = CO32-
#       HCO3- + Ca2+               = CaHCO3+
#       HCO3-        + Mg2+        = MgHCO3+
#       HCO3-               + Fe2+ = FeHCO3+
#
# The kinetic reaction that dissolves dolomite involves all 5 primary species.
#
# -2H+ + 2HCO3- + Ca2+ + 0.8Mg2+ + 0.2Fe2+ = CaMg0.8Fe0.2(CO3)2
#
# The initial concentration of precipitated dolomite is high, so it starts
# to dissolve immediately, increasing the concentrations of the primary species.
#
# Only single-phase, fully saturated physics is used.
# The pressure gradient is fixed, so that the Darcy velocity is 0.1m/s.
#
# Primary species are injected from the left side, and they flow to the right.
# Less dolomite dissolution therefore occurs on the left side (where
# the primary species have higher concentration).
#
# This test is more fully documented in tutorial_13
[Mesh]
  type = GeneratedMesh
  dim = 1
  nx = 100
  xmax = 1
[]
[Variables]
  [h+]
  []
  [hco3-]
  []
  [ca2+]
  []
  [mg2+]
  []
  [fe2+]
  []
[]
[AuxVariables]
  [eqm_k0]
    initial_condition = 2.19E6
  []
  [eqm_k1]
    initial_condition = 4.73E-11
  []
  [eqm_k2]
    initial_condition = 0.222
  []
  [eqm_k3]
    initial_condition = 1E-2
  []
  [eqm_k4]
    initial_condition = 1E-3
  []
  [kinetic_k]
    initial_condition = 326.2
  []
  [pressure]
  []
  [dolomite]
    family = MONOMIAL
    order = CONSTANT
  []
  [dolomite_initial]
    initial_condition = 1E-7
  []
[]
[AuxKernels]
  [dolomite]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = dolomite
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[ICs]
  [pressure_ic]
    type = FunctionIC
    variable = pressure
    function = '(1 - x) * 1E6'
  []
  [h+_ic]
    type = BoundingBoxIC
    variable = h+
    x1 = 0.0
    y1 = 0.0
    x2 = 1.0e-10
    y2 = 0.25
    inside = 5.0e-2
    outside = 1.0e-6
  []
  [hco3_ic]
    type = BoundingBoxIC
    variable = hco3-
    x1 = 0.0
    y1 = 0.0
    x2 = 1.0e-10
    y2 = 0.25
    inside = 5.0e-2
    outside = 1.0e-6
  []
  [ca2_ic]
    type = BoundingBoxIC
    variable = ca2+
    x1 = 0.0
    y1 = 0.0
    x2 = 1.0e-10
    y2 = 0.25
    inside = 5.0e-2
    outside = 1.0e-6
  []
  [mg2_ic]
    type = BoundingBoxIC
    variable = mg2+
    x1 = 0.0
    y1 = 0.0
    x2 = 1.0e-10
    y2 = 0.25
    inside = 5.0e-2
    outside = 1.0e-6
  []
  [fe2_ic]
    type = BoundingBoxIC
    variable = fe2+
    x1 = 0.0
    y1 = 0.0
    x2 = 1.0e-10
    y2 = 0.25
    inside = 5.0e-2
    outside = 1.0e-6
  []
[]
[Kernels]
  [h+_ie]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = h+
  []
  [h+_conv]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = h+
  []
  [predis_h+]
    type = PorousFlowPreDis
    variable = h+
    mineral_density = 2875.0
    stoichiometry = -2
  []
  [hco3-_ie]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = hco3-
  []
  [hco3-_conv]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    variable = hco3-
  []
  [predis_hco3-]
    type = PorousFlowPreDis
    variable = hco3-
    mineral_density = 2875.0
    stoichiometry = 2
  []
  [ca2+_ie]
    type = PorousFlowMassTimeDerivative
    fluid_component = 2
    variable = ca2+
  []
  [ca2+_conv]
    type = PorousFlowAdvectiveFlux
    fluid_component = 2
    variable = ca2+
  []
  [predis_ca2+]
    type = PorousFlowPreDis
    variable = ca2+
    mineral_density = 2875.0
    stoichiometry = 1
  []
  [mg2+_ie]
    type = PorousFlowMassTimeDerivative
    fluid_component = 3
    variable = mg2+
  []
  [mg2+_conv]
    type = PorousFlowAdvectiveFlux
    fluid_component = 3
    variable = mg2+
  []
  [predis_mg2+]
    type = PorousFlowPreDis
    variable = mg2+
    mineral_density = 2875.0
    stoichiometry = 0.8
  []
  [fe2+_ie]
    type = PorousFlowMassTimeDerivative
    fluid_component = 4
    variable = fe2+
  []
  [fe2+_conv]
    type = PorousFlowAdvectiveFlux
    fluid_component = 4
    variable = fe2+
  []
  [predis_fe2+]
    type = PorousFlowPreDis
    variable = fe2+
    mineral_density = 2875.0
    stoichiometry = 0.2
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'h+ hco3- ca2+ mg2+ fe2+'
    number_fluid_phases = 1
    number_fluid_components = 6
    number_aqueous_equilibrium = 5
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    viscosity = 1E-3
  []
[]
[BCs]
  [hco3-_left]
    type = DirichletBC
    variable = hco3-
    boundary = left
    value = 5E-2
  []
  [h+_left]
    type = DirichletBC
    variable = h+
    boundary = left
    value = 5E-2
  []
  [ca2+_left]
    type = DirichletBC
    variable = ca2+
    boundary = left
    value = 5E-2
  []
  [mg2+_left]
    type = DirichletBC
    variable = mg2+
    boundary = left
    value = 5E-2
  []
  [fe2+_left]
    type = DirichletBC
    variable = fe2+
    boundary = left
    value = 5E-2
  []
  [hco3-_right]
    type = DirichletBC
    variable = hco3-
    boundary = right
    value = 1E-6
  []
  [h+_right]
    type = DirichletBC
    variable = h+
    boundary = right
    value = 1e-6
  []
  [ca2+_right]
    type = DirichletBC
    variable = ca2+
    boundary = right
    value = 1E-6
  []
  [mg2+_right]
    type = DirichletBC
    variable = mg2+
    boundary = right
    value = 1E-6
  []
  [fe2+_right]
    type = DirichletBC
    variable = fe2+
    boundary = right
    value = 1E-6
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 298.15
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [equilibrium_massfrac]
    type = PorousFlowMassFractionAqueousEquilibriumChemistry
    mass_fraction_vars = 'h+ hco3- ca2+ mg2+ fe2+'
    num_reactions = 5
    equilibrium_constants = 'eqm_k0 eqm_k1 eqm_k2 eqm_k3 eqm_k4'
    primary_activity_coefficients = '1 1 1 1 1'
    secondary_activity_coefficients = '1 1 1 1 1'
    reactions = '1 1 0 0 0
                -1 1 0 0 0
                 0 1 1 0 0
                 0 1 0 1 0
                 0 1 0 0 1'
  []
  [kinetic]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'h+ hco3- ca2+ mg2+ fe2+'
    num_reactions = 1
    equilibrium_constants = kinetic_k
    primary_activity_coefficients = '1 1 1 1 1'
    reactions = '-2 2 1 0.8 0.2'
    specific_reactive_surface_area = '1.2E-8'
    kinetic_rate_constant = '3E-4'
    activation_energy = '1.5e4'
    molar_volume = 64365.0
    gas_constant = 8.314
    reference_temperature = 298.15
  []
  [dolomite_conc]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = dolomite_initial
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.2
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1E-10 0 0 0 1E-10 0 0 0 1E-10'
  []
  [relp]
    type = PorousFlowRelativePermeabilityConst
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 0.1
  []
[]
[Preconditioning]
  active = basic
  [basic]
    type = SMP
    full = true
    petsc_options = '-ksp_diagonal_scale -ksp_diagonal_scale_fix'
    petsc_options_iname = '-pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = ' asm      lu           NONZERO                   2'
  []
  [preferred_but_might_not_be_installed]
    type = SMP
    full = true
    petsc_options_iname = '-pc_type -pc_factor_mat_solver_package'
    petsc_options_value = ' lu       mumps'
  []
[]
[Outputs]
  print_linear_residuals = false
  perf_graph = true
  exodus = true
[]
(modules/porous_flow/test/tests/chemistry/except10.i)
# Exception test.
# Incorrect number of activation energies
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = Diffusion
    variable = a
  []
  [b]
    type = Diffusion
    variable = b
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '1 1'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = 1.0e-8
    activation_energy = '1.5e4 1'
    molar_volume = 1
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/jacobian/chem06.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with no temperature dependence, with one primary variable = 0 and stoichiometry = 1
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.2
  []
  [b]
    initial_condition = 0.0
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [temp]
    initial_condition = 0.5
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E5
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E5
    stoichiometry = 3
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '0.5 0.8'
    reactions = '3 1'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/jacobian/chem13.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with temperature, with three primary variables and four reactions, and some zero concentrations
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0
  []
  [b]
    initial_condition = 0
  []
  [c]
    initial_condition = 0
  []
  [temp]
    initial_condition = 0.5
  []
[]
[AuxVariables]
  [eqm_k0]
    initial_condition = 1.234
  []
  [eqm_k1]
    initial_condition = 1.999
  []
  [eqm_k2]
    initial_condition = 0.789
  []
  [eqm_k3]
    initial_condition = 1.111
  []
  [ini_sec_conc0]
    initial_condition = 0.02
  []
  [ini_sec_conc1]
    initial_condition = 0.04
  []
  [ini_sec_conc2]
    initial_condition = 0.06
  []
  [ini_sec_conc3]
    initial_condition = 0.08
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = '1E10 2E10 3E10 4E10'
    stoichiometry = '1 1 2 0'
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = '1.1E10 2.2E10 3.3E10 4.4E10'
    stoichiometry = '2 -2 0 0.5'
  []
  [c]
    type = PorousFlowPreDis
    variable = c
    mineral_density = '0.1E10 0.2E10 0.3E10 0.4E10'
    stoichiometry = '3 -3 0 1'
  []
  [temp]
    type = Diffusion
    variable = temp
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b c temp'
    number_fluid_phases = 1
    number_fluid_components = 4
    number_aqueous_kinetic = 4
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b c'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b c'
    num_reactions = 4
    equilibrium_constants = 'eqm_k0 eqm_k1 eqm_k2 eqm_k3'
    primary_activity_coefficients = '0.5 0.8 0.9'
    reactions = '0.5 2 3
                 1.5 -2 3
                 2 0 0
                 0 0.5 1'
    specific_reactive_surface_area = '-44.4E-2 22.1E-2 32.1E-1 -50E-2'
    kinetic_rate_constant = '0.678 0.999 1.23 0.3'
    activation_energy = '4.4 3.3 4.5 4.0'
    molar_volume = '3.3 4.4 5.5 6.6'
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = '1.0 1.1 1.2 0.9'
    eta_exponent = '1.2 1.01 1.1 1.2'
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = 'ini_sec_conc0 ini_sec_conc1 ini_sec_conc2 ini_sec_conc3'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/jacobian/chem09.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with temperature, with one primary variable = 0 and stoichiometry = 1
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.0
  []
  [b]
    initial_condition = 0.2
  []
  [temp]
    initial_condition = 0.5
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E10
    stoichiometry = 1
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E10
    stoichiometry = 3
  []
  [temp]
    type = Diffusion
    variable = temp
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b temp'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '0.5 0.8'
    reactions = '1 3'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/jacobian/chem12.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with temperature, with three primary variables and four reactions
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.05
  []
  [b]
    initial_condition = 0.1
  []
  [c]
    initial_condition = 0.15
  []
  [temp]
    initial_condition = 0.5
  []
[]
[AuxVariables]
  [eqm_k0]
    initial_condition = 1.234
  []
  [eqm_k1]
    initial_condition = 1.999
  []
  [eqm_k2]
    initial_condition = 0.789
  []
  [eqm_k3]
    initial_condition = 1.111
  []
  [ini_sec_conc0]
    initial_condition = 0.02
  []
  [ini_sec_conc1]
    initial_condition = 0.04
  []
  [ini_sec_conc2]
    initial_condition = 0.06
  []
  [ini_sec_conc3]
    initial_condition = 0.08
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = '1E10 2E10 3E10 4E10'
    stoichiometry = '1 1 2 0'
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = '1.1E10 2.2E10 3.3E10 4.4E10'
    stoichiometry = '2 -2 0 0.5'
  []
  [c]
    type = PorousFlowPreDis
    variable = c
    mineral_density = '0.1E10 0.2E10 0.3E10 0.4E10'
    stoichiometry = '3 -3 0 1'
  []
  [temp]
    type = Diffusion
    variable = temp
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b c temp'
    number_fluid_phases = 1
    number_fluid_components = 4
    number_aqueous_kinetic = 4
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b c'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b c'
    num_reactions = 4
    equilibrium_constants = 'eqm_k0 eqm_k1 eqm_k2 eqm_k3'
    primary_activity_coefficients = '0.5 0.8 0.9'
    reactions = '1 2 3
                 1 -2 -3
                 2 0 0
                 0 0.5 1'
    specific_reactive_surface_area = '-44.4E-2 22.1E-2 32.1E-1 -50E-2'
    kinetic_rate_constant = '0.678 0.999 1.23 0.3'
    activation_energy = '4.4 3.3 4.5 4.0'
    molar_volume = '3.3 4.4 5.5 6.6'
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = '1.0 1.1 1.2 0.9'
    eta_exponent = '1.2 1.01 1.1 1.2'
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = 'ini_sec_conc0 ini_sec_conc1 ini_sec_conc2 ini_sec_conc3'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/jacobian/chem05.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with no temperature dependence, with one primary variable = 0 and stoichiometry > 1
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.0
  []
  [b]
    initial_condition = 0.2
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
  [temp]
    initial_condition = 0.5
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E5
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E5
    stoichiometry = 3
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '0.5 0.8'
    reactions = '2 3'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1.1
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/examples/tutorial/07.i)
# Darcy flow with a tracer that precipitates causing mineralisation and porosity changes and permeability changes
[Mesh]
  [annular]
    type = AnnularMeshGenerator
    nr = 10
    rmin = 1.0
    rmax = 10
    growth_r = 1.4
    nt = 4
    dmin = 0
    dmax = 90
  []
  [make3D]
    input = annular
    type = MeshExtruderGenerator
    extrusion_vector = '0 0 12'
    num_layers = 3
    bottom_sideset = 'bottom'
    top_sideset = 'top'
  []
  [shift_down]
    type = TransformGenerator
    transform = TRANSLATE
    vector_value = '0 0 -6'
    input = make3D
  []
  [aquifer]
    type = SubdomainBoundingBoxGenerator
    block_id = 1
    bottom_left = '0 0 -2'
    top_right = '10 10 2'
    input = shift_down
  []
  [injection_area]
    type = ParsedGenerateSideset
    combinatorial_geometry = 'x*x+y*y<1.01'
    included_subdomains = 1
    new_sideset_name = 'injection_area'
    input = 'aquifer'
  []
  [rename]
    type = RenameBlockGenerator
    old_block = '0 1'
    new_block = 'caps aquifer'
    input = 'injection_area'
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Variables]
  [porepressure]
  []
  [tracer_concentration]
  []
[]
[PorousFlowFullySaturated]
  porepressure = porepressure
  coupling_type = Hydro
  gravity = '0 0 0'
  fp = the_simple_fluid
  mass_fraction_vars = tracer_concentration
  number_aqueous_kinetic = 1
  temperature = 283.0
  stabilization = none # Note to reader: try this with other stabilization and compare the results
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 0.1
  []
  [mineral_conc]
    family = MONOMIAL
    order = CONSTANT
  []
  [initial_and_reference_conc]
    initial_condition = 0
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
  [permeability]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral_conc]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral_conc
  []
  [porosity]
    type = PorousFlowPropertyAux
    property = porosity
    variable = porosity
  []
  [permeability]
    type = PorousFlowPropertyAux
    property = permeability
    column = 0
    row = 0
    variable = permeability
  []
[]
[Kernels]
  [precipitation_dissolution]
    type = PorousFlowPreDis
    mineral_density = 1000.0
    stoichiometry = 1
    variable = tracer_concentration
  []
[]
[BCs]
  [constant_injection_of_tracer]
    type = PorousFlowSink
    variable = tracer_concentration
    flux_function = -5E-3
    boundary = injection_area
  []
  [constant_outer_porepressure]
    type = DirichletBC
    variable = porepressure
    value = 0
    boundary = rmax
  []
[]
[FluidProperties]
  [the_simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2E9
    viscosity = 1.0E-3
    density0 = 1000.0
  []
[]
[Materials]
  [porosity_mat]
    type = PorousFlowPorosity
    porosity_zero = 0.1
    chemical = true
    initial_mineral_concentrations = initial_and_reference_conc
    reference_chemistry = initial_and_reference_conc
  []
  [permeability_aquifer]
    type = PorousFlowPermeabilityKozenyCarman
    block = aquifer
    k0 = 1E-14
    m = 2
    n = 3
    phi0 = 0.1
    poroperm_function = kozeny_carman_phi0
  []
  [permeability_caps]
    type = PorousFlowPermeabilityKozenyCarman
    block = caps
    k0 = 1E-15
    k_anisotropy = '1 0 0  0 1 0  0 0 0.1'
    m = 2
    n = 3
    phi0 = 0.1
    poroperm_function = kozeny_carman_phi0
  []
  [precipitation_dissolution_mat]
    type = PorousFlowAqueousPreDisChemistry
    reference_temperature = 283.0
    activation_energy = 1 # irrelevant because T=Tref
    equilibrium_constants = eqm_k # equilibrium tracer concentration
    kinetic_rate_constant = 1E-8
    molar_volume = 1
    num_reactions = 1
    primary_activity_coefficients = 1
    primary_concentrations = tracer_concentration
    reactions = 1
    specific_reactive_surface_area = 1
  []
  [mineral_concentration]
    type = PorousFlowAqueousPreDisMineral
  []
[]
[Preconditioning]
  active = basic
  [basic]
    type = SMP
    full = true
    petsc_options = '-ksp_diagonal_scale -ksp_diagonal_scale_fix'
    petsc_options_iname = '-pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = ' asm      lu           NONZERO                   2'
  []
  [preferred_but_might_not_be_installed]
    type = SMP
    full = true
    petsc_options_iname = '-pc_type -pc_factor_mat_solver_package'
    petsc_options_value = ' lu       mumps'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1E6
  dt = 1E5
  nl_abs_tol = 1E-10
[]
[Outputs]
  exodus = true
[]
(modules/porous_flow/test/tests/chemistry/except15.i)
# Exception test
# Incorrect number of secondary densities
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = '1 1'
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 1
    stoichiometry = 3
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '2 3'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = 1.0e-8
    activation_energy = 1.5e4
    molar_volume = 1
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/jacobian/chem08.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Dissolution with temperature, with one primary variable = 0 and stoichiometry > 1
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.2
  []
  [b]
    initial_condition = 0.0
  []
  [temp]
    initial_condition = 0.5
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E10
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E10
    stoichiometry = 3
  []
  [temp]
    type = Diffusion
    variable = temp
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b temp'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '0.5 0.8'
    reactions = '2 3'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1.1
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options = '-snes_test_display'
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/chemistry/2species_predis.i)
# PorousFlow analogy of chemical_reactions/test/tests/solid_kinetics/2species_without_action.i
#
# Simple equilibrium reaction example to illustrate the use of PorousFlowAqueousPreDisChemistry
#
# In this example, two primary species a and b diffuse towards each other from
# opposite ends of a porous medium, reacting when they meet to form a mineral
# precipitate. The kinetic reaction is
#
# a + b = mineral
#
# where a and b are the primary species (reactants), and mineral is the precipitate.
# At the time of writing, the results of this test differ from chemical_reactions because
# in PorousFlow the mineral_concentration is measured in m^3 (precipitate) / m^3 (porous_material)
# in chemical_reactions the mineral_concentration is measured in m^3 (precipitate) / m^3 (fluid)
# ie, PorousFlow_mineral_concentration = porosity * chemical_reactions_mineral_concentration
[Mesh]
  type = GeneratedMesh
  dim = 2
  xmax = 1
  ymax = 1
  nx = 40
[]
[Variables]
  [a]
    order = FIRST
    family = LAGRANGE
    initial_condition = 0
  []
  [b]
    order = FIRST
    family = LAGRANGE
    initial_condition = 0
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[Kernels]
  [mass_a]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = a
  []
  [diff_a]
    type = PorousFlowDispersiveFlux
    variable = a
    fluid_component = 0
    disp_trans = 0
    disp_long = 0
  []
  [predis_a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1000
    stoichiometry = 1
  []
  [mass_b]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = b
  []
  [diff_b]
    type = PorousFlowDispersiveFlux
    variable = b
    fluid_component = 1
    disp_trans = 0
    disp_long = 0
  []
  [predis_b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 1000
    stoichiometry = 1
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e9 # huge, so mimic chemical_reactions
    density0 = 1000
    thermal_expansion = 0
    viscosity = 1e-3
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 298.15
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [chem]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '1 1'
    specific_reactive_surface_area = '1.0'
    kinetic_rate_constant = '1.0e-8'
    activation_energy = '1.5e4'
    molar_volume = 1
    gas_constant = 8.314
    reference_temperature = 298.15
  []
  [mineral_conc]
    type = PorousFlowAqueousPreDisMineral
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.4
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    # porous_flow permeability / porous_flow viscosity = chemical_reactions conductivity = 4E-3
    permeability = '4E-6 0 0 0 4E-6 0 0 0 4E-6'
  []
  [relp]
    type = PorousFlowRelativePermeabilityConst
    phase = 0
  []
  [diff]
    type = PorousFlowDiffusivityConst
    # porous_flow diffusion_coeff * tortuousity * porosity = chemical_reactions diffusivity = 5E-4
    diffusion_coeff = '12.5E-4 12.5E-4 12.5E-4'
    tortuosity = 1.0
  []
[]
[BCs]
  [a_left]
    type = DirichletBC
    variable = a
    boundary = left
    value = 1.0e-2
  []
  [a_right]
    type = DirichletBC
    variable = a
    boundary = right
    value = 0
  []
  [b_left]
    type = DirichletBC
    variable = b
    boundary = left
    value = 0
  []
  [b_right]
    type = DirichletBC
    variable = b
    boundary = right
    value = 1.0e-2
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 5
  end_time = 50
[]
[Outputs]
  print_linear_residuals = true
  exodus = true
  perf_graph = true
  hide = eqm_k
[]
(modules/porous_flow/test/tests/jacobian/chem04.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Precipitation with temperature
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.6
  []
  [b]
    initial_condition = 0.4
  []
  [temp]
    initial_condition = 0.5
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E-5
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E-5
    stoichiometry = 3
  []
  [temp]
    type = Diffusion
    variable = temp
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b temp'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '2.5 3.8'
    reactions = '1.1 1.2'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1.1
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]
(modules/porous_flow/test/tests/chemistry/dissolution.i)
# The dissolution reaction
#
# a <==> mineral
#
# produces "mineral".  Using mineral_density = fluid_density, theta = 1 = eta, the DE is
#
# a' = -(mineral / porosity)' = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#
# The following parameters are used
#
# T_ref = 0.5 K
# T = 1 K
# activation_energy = 3 J/mol
# gas_constant = 6 J/(mol K)
# kinetic_rate_at_ref_T = 0.60653 mol/(m^2 s)
# These give rate = 0.60653 * exp(1/2) = 1 mol/(m^2 s)
#
# surf_area = 0.5 m^2/L
# molar_volume = 2 L/mol
# These give rate * surf_area * molar_vol = 1 s^-1
#
# equilibrium_constant = 0.5 (dimensionless)
# primary_activity_coefficient = 2 (dimensionless)
# stoichiometry = 1 (dimensionless)
# This means that 1 - (1 / eqm_const) * (act_coeff * a)^stoi = 1 - 4 a, which is positive for a < 0.25, ie dissolution for a(t=0) < 0.25
#
# The solution of the DE is
# a = eqm_const / act_coeff + (a(t=0) - eqm_const / act_coeff) exp(-rate * surf_area * molar_vol * act_coeff * t / eqm_const)
#   = 0.25 + (a(t=0) - 0.25) exp(-4 * t)
# c = c(t=0) - (a - a(t=0)) * porosity
#
# This test checks that (a + c / porosity) is time-independent, and that a follows the above solution
#
# Aside:
#    The exponential curve is not followed exactly because moose actually solves
#    (a - a_old)/dt = rate * surf_area * molar_vol (1 - (1 / eqm_const) * (act_coeff * a)^stoi)
#    which does not give an exponential exactly, except in the limit dt->0
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.05
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 0.5
  []
  [pressure]
  []
  [ini_mineral_conc]
    initial_condition = 0.3
  []
  [mineral]
    family = MONOMIAL
    order = CONSTANT
  []
  [should_be_static]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [mineral]
    type = PorousFlowPropertyAux
    property = mineral_concentration
    mineral_species = 0
    variable = mineral
  []
  [should_be_static]
    type = ParsedAux
    coupled_variables = 'mineral a'
    expression = 'a + mineral / 0.1'
    variable = should_be_static
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [mass_a]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = a
  []
  [pre_dis]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1000
    stoichiometry = 1
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = a
    number_fluid_phases = 1
    number_fluid_components = 2
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e9 # huge, so mimic chemical_reactions
    density0 = 1000
    thermal_expansion = 0
    viscosity = 1e-3
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 1
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [mass_frac]
    type = PorousFlowMassFraction
    mass_fraction_vars = a
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = a
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = 2
    reactions = 1
    specific_reactive_surface_area = 0.5
    kinetic_rate_constant = 0.6065306597126334
    activation_energy = 3
    molar_volume = 2
    gas_constant = 6
    reference_temperature = 0.5
  []
  [mineral_conc]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_mineral_conc
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  nl_abs_tol = 1E-10
  dt = 0.01
  end_time = 1
[]
[Postprocessors]
  [a]
    type = PointValue
    point = '0 0 0'
    variable = a
  []
  [should_be_static]
    type = PointValue
    point = '0 0 0'
    variable = should_be_static
  []
[]
[Outputs]
  time_step_interval = 10
  csv = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/chemistry/except12.i)
# Exception test.
# Incorrect number of theta exponents
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
  []
  [b]
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = Diffusion
    variable = a
  []
  [b]
    type = Diffusion
    variable = b
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1E-6
  []
  [pressure]
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '1 1'
    reactions = '1 1'
    specific_reactive_surface_area = 1.0
    kinetic_rate_constant = 1.0e-8
    activation_energy = 1.5e4
    molar_volume = 1
    theta_exponent = '1 1'
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
  []
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1
[]
(modules/porous_flow/test/tests/jacobian/chem02.i)
# PorousFlowPreDis, which is essentially checking the derivatives of the secondary concentrations in PorousFlowMassFractionAqueousPreDisChemistry
# Precipitation with temperature
[Mesh]
  type = GeneratedMesh
  dim = 1
[]
[Variables]
  [a]
    initial_condition = 0.6
  []
  [b]
    initial_condition = 0.4
  []
[]
[AuxVariables]
  [eqm_k]
    initial_condition = 1.234
  []
  [temp]
    initial_condition = 0.5
  []
  [ini_sec_conc]
    initial_condition = 0.222
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Kernels]
  [a]
    type = PorousFlowPreDis
    variable = a
    mineral_density = 1E5
    stoichiometry = 2
  []
  [b]
    type = PorousFlowPreDis
    variable = b
    mineral_density = 2.2E5
    stoichiometry = 3
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'a b'
    number_fluid_phases = 1
    number_fluid_components = 3
    number_aqueous_kinetic = 1
  []
[]
[AuxVariables]
  [pressure]
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.9
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pressure
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'a b'
  []
  [predis]
    type = PorousFlowAqueousPreDisChemistry
    primary_concentrations = 'a b'
    num_reactions = 1
    equilibrium_constants = eqm_k
    primary_activity_coefficients = '2.5 3.8'
    reactions = '1.1 1.2'
    specific_reactive_surface_area = -44.4E-2
    kinetic_rate_constant = 0.678
    activation_energy = 4.4
    molar_volume = 3.3
    reference_temperature = 1
    gas_constant = 7.4
    theta_exponent = 1.1
    eta_exponent = 1.2
  []
  [mineral]
    type = PorousFlowAqueousPreDisMineral
    initial_concentrations = ini_sec_conc
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.1
  end_time = 0.1
[]
[Preconditioning]
  [check]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it -snes_type'
    petsc_options_value = 'bcgs bjacobi 1E-15 1E-10 10000 test'
  []
[]