- 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
 - boundaryThe list of boundary IDs from the mesh where this object applies
C++ Type:std::vector<BoundaryName>
Controllable:No
Description:The list of boundary IDs from the mesh where this object applies
 - variableThe name of the variable that this residual object operates on
C++ Type:NonlinearVariableName
Unit:(no unit assumed)
Controllable:No
Description:The name of the variable that this residual object operates on
 
PorousFlowSink
Applies a flux sink to a boundary.
This sink is where is a MOOSE Function of time and position on the boundary.
If then the boundary condition will act as a sink, while if the boundary condition acts as a source. If applied to a fluid-component equation, the function has units kg.m.s. If applied to the heat equation, the function has units J.m.s. These units are potentially modified if the extra building blocks enumerated below are used.
In addition, the sink may be multiplied by any or all of the following quantities through the optional parameters list.
Fluid relative permeability
Fluid mobility (, where is the normal vector to the boundary)
Fluid mass fraction
Fluid internal energy
Thermal conductivity
See boundary conditions for many more details and discussion.
Input Parameters
- displacementsThe displacements
C++ Type:std::vector<VariableName>
Unit:(no unit assumed)
Controllable:No
Description:The displacements
 - fluid_phaseIf supplied, then this BC will potentially be a function of fluid pressure, and you can use mass_fraction_component, use_mobility, use_relperm, use_enthalpy and use_energy. If not supplied, then this BC can only be a function of temperature
C++ Type:unsigned int
Controllable:No
Description:If supplied, then this BC will potentially be a function of fluid pressure, and you can use mass_fraction_component, use_mobility, use_relperm, use_enthalpy and use_energy. If not supplied, then this BC can only be a function of temperature
 - flux_function1The flux. The flux is OUT of the medium: hence positive values of this function means this BC will act as a SINK, while negative values indicate this flux will be a SOURCE. The functional form is useful for spatially or temporally varying sinks. Without any use_*, this function is measured in kg.m^-2.s^-1 (or J.m^-2.s^-1 for the case with only heat and no fluids)
Default:1
C++ Type:FunctionName
Unit:(no unit assumed)
Controllable:No
Description:The flux. The flux is OUT of the medium: hence positive values of this function means this BC will act as a SINK, while negative values indicate this flux will be a SOURCE. The functional form is useful for spatially or temporally varying sinks. Without any use_*, this function is measured in kg.m^-2.s^-1 (or J.m^-2.s^-1 for the case with only heat and no fluids)
 - mass_fraction_componentThe index corresponding to a fluid component. If supplied, the flux will be multiplied by the nodal mass fraction for the component
C++ Type:unsigned int
Controllable:No
Description:The index corresponding to a fluid component. If supplied, the flux will be multiplied by the nodal mass fraction for the component
 - matrix_onlyFalseWhether this object is only doing assembly to matrices (no vectors)
Default:False
C++ Type:bool
Controllable:No
Description:Whether this object is only doing assembly to matrices (no vectors)
 - use_enthalpyFalseIf true, then fluxes are multiplied by enthalpy. In this case bare_flux is measured in kg.m^-2.s^-1 / (J.kg). This can be used in conjunction with other use_*
Default:False
C++ Type:bool
Controllable:No
Description:If true, then fluxes are multiplied by enthalpy. In this case bare_flux is measured in kg.m^-2.s^-1 / (J.kg). This can be used in conjunction with other use_*
 - use_internal_energyFalseIf true, then fluxes are multiplied by fluid internal energy. In this case bare_flux is measured in kg.m^-2.s^-1 / (J.kg). This can be used in conjunction with other use_*
Default:False
C++ Type:bool
Controllable:No
Description:If true, then fluxes are multiplied by fluid internal energy. In this case bare_flux is measured in kg.m^-2.s^-1 / (J.kg). This can be used in conjunction with other use_*
 - use_mobilityFalseIf true, then fluxes are multiplied by (density*permeability_nn/viscosity), where the '_nn' indicates the component normal to the boundary. In this case bare_flux is measured in Pa.m^-1. This can be used in conjunction with other use_*
Default:False
C++ Type:bool
Controllable:No
Description:If true, then fluxes are multiplied by (density*permeability_nn/viscosity), where the '_nn' indicates the component normal to the boundary. In this case bare_flux is measured in Pa.m^-1. This can be used in conjunction with other use_*
 - use_relpermFalseIf true, then fluxes are multiplied by relative permeability. This can be used in conjunction with other use_*
Default:False
C++ Type:bool
Controllable:No
Description:If true, then fluxes are multiplied by relative permeability. This can be used in conjunction with other use_*
 - use_thermal_conductivityFalseIf true, then fluxes are multiplied by thermal conductivity projected onto the normal direction. This can be used in conjunction with other use_*
Default:False
C++ Type:bool
Controllable:No
Description:If true, then fluxes are multiplied by thermal conductivity projected onto the normal direction. This can be used in conjunction with other use_*
 
Optional Parameters
- absolute_value_vector_tagsThe tags for the vectors this residual object should fill with the absolute value of the residual contribution
C++ Type:std::vector<TagName>
Controllable:No
Description:The tags for the vectors this residual object should fill with the absolute value of the residual contribution
 - extra_matrix_tagsThe extra tags for the matrices this Kernel should fill
C++ Type:std::vector<TagName>
Controllable:No
Description:The extra tags for the matrices this Kernel should fill
 - extra_vector_tagsThe extra tags for the vectors this Kernel should fill
C++ Type:std::vector<TagName>
Controllable:No
Description:The extra tags for the vectors this Kernel should fill
 - matrix_tagssystemThe tag for the matrices this Kernel should fill
Default:system
C++ Type:MultiMooseEnum
Options:nontime, system
Controllable:No
Description:The tag for the matrices this Kernel should fill
 - vector_tagsnontimeThe tag for the vectors this Kernel should fill
Default:nontime
C++ Type:MultiMooseEnum
Options:nontime, time
Controllable:No
Description:The tag for the vectors this Kernel should fill
 
Contribution To Tagged Field Data 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.
 - diag_save_inThe name of auxiliary variables to save this BC's diagonal jacobian contributions to. Everything about that variable must match everything about this variable (the type, what blocks it's on, etc.)
C++ Type:std::vector<AuxVariableName>
Unit:(no unit assumed)
Controllable:No
Description:The name of auxiliary variables to save this BC's diagonal jacobian contributions to. Everything about that variable must match everything about this variable (the type, what blocks it's on, etc.)
 - 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
 - save_inThe name of auxiliary variables to save this BC's residual contributions to. Everything about that variable must match everything about this variable (the type, what blocks it's on, etc.)
C++ Type:std::vector<AuxVariableName>
Unit:(no unit assumed)
Controllable:No
Description:The name of auxiliary variables to save this BC's residual contributions to. Everything about that variable must match everything about this variable (the type, what blocks it's on, etc.)
 - 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
 - skip_execution_outside_variable_domainFalseWhether to skip execution of this boundary condition when the variable it applies to is not defined on the boundary. This can facilitate setups with moving variable domains and fixed boundaries. Note that the FEProblem boundary-restricted integrity checks will also need to be turned off if using this option
Default:False
C++ Type:bool
Controllable:No
Description:Whether to skip execution of this boundary condition when the variable it applies to is not defined on the boundary. This can facilitate setups with moving variable domains and fixed boundaries. Note that the FEProblem boundary-restricted integrity checks will also need to be turned off if using this option
 - 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
- 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/examples/ates/ates.i)
 - (modules/porous_flow/examples/tutorial/08.i)
 - (modules/porous_flow/examples/thm_example/2D_c.i)
 - (modules/porous_flow/examples/tutorial/10.i)
 - (modules/porous_flow/examples/tutorial/11_2D.i)
 - (modules/porous_flow/test/tests/fluidstate/theis_brineco2_nonisothermal.i)
 - (modules/porous_flow/test/tests/sinks/s02.i)
 - (modules/porous_flow/test/tests/sinks/s08.i)
 - (modules/porous_flow/test/tests/sinks/s11.i)
 - (modules/porous_flow/test/tests/fluidstate/theis_nonisothermal.i)
 - (modules/porous_flow/test/tests/infiltration_and_drainage/rsc02.i)
 - (modules/porous_flow/test/tests/sinks/injection_production_eg_outflowBC.i)
 - (modules/porous_flow/test/tests/infiltration_and_drainage/rd01.i)
 - (modules/porous_flow/examples/groundwater/ex02_abstraction.i)
 - (modules/porous_flow/examples/tutorial/08_KT.i)
 - (modules/porous_flow/examples/restart/gas_injection_new_mesh.i)
 - (modules/porous_flow/test/tests/sinks/s10.i)
 - (modules/porous_flow/test/tests/sinks/s12.i)
 - (modules/porous_flow/examples/thm_example/2D.i)
 - (modules/porous_flow/test/tests/sinks/s01.i)
 - (modules/porous_flow/test/tests/sinks/s03.i)
 - (modules/porous_flow/examples/restart/gas_injection.i)
 - (modules/porous_flow/test/tests/infiltration_and_drainage/rsc01.i)
 - (modules/porous_flow/examples/tutorial/11.i)
 - (modules/porous_flow/examples/groundwater/ex02_steady_state.i)
 - (modules/porous_flow/examples/tutorial/07.i)
 - (modules/porous_flow/test/tests/infiltration_and_drainage/bw01.i)
 - (modules/porous_flow/examples/multiapp_fracture_flow/single_fracture_heat_transfer/fracture_app.i)
 - (modules/porous_flow/test/tests/sinks/s07.i)
 - (modules/porous_flow/test/tests/hysteresis/1phase_bc.i)
 - (modules/porous_flow/test/tests/infiltration_and_drainage/bw02.i)
 - (modules/porous_flow/test/tests/sinks/injection_production_eg.i)
 - (modules/porous_flow/test/tests/fluidstate/coldwater_injection_radial.i)
 
Child Objects
(modules/porous_flow/examples/ates/ates.i)
# Simulation designed to assess the recovery efficiency of a single-well ATES system
# Using KT stabilisation
# Boundary conditions: fixed porepressure and temperature at top, bottom and far end of model.
#####################################
flux_limiter = minmod # minmod, vanleer, mc, superbee, none
# depth of top of aquifer (m)
depth = 400
inject_fluid_mass = 1E8 # kg
produce_fluid_mass = ${inject_fluid_mass} # kg
inject_temp = 90 # degC
inject_time = 91 # days
store_time = 91 # days
produce_time = 91 # days
rest_time = 91 # days
num_cycles = 5 # Currently needs to be <= 10
cycle_length = '${fparse inject_time + store_time + produce_time + rest_time}'
end_simulation = '${fparse cycle_length * num_cycles}'
# Note: I have setup 10 cycles but you can set num_cycles less than 10.
start_injection1 = 0
start_injection2 = ${cycle_length}
start_injection3 = '${fparse cycle_length * 2}'
start_injection4 = '${fparse cycle_length * 3}'
start_injection5 = '${fparse cycle_length * 4}'
start_injection6 = '${fparse cycle_length * 5}'
start_injection7 = '${fparse cycle_length * 6}'
start_injection8 = '${fparse cycle_length * 7}'
start_injection9 = '${fparse cycle_length * 8}'
start_injection10 = '${fparse cycle_length * 9}'
end_injection1 = '${fparse start_injection1 + inject_time}'
end_injection2 = '${fparse start_injection2 + inject_time}'
end_injection3 = '${fparse start_injection3 + inject_time}'
end_injection4 = '${fparse start_injection4 + inject_time}'
end_injection5 = '${fparse start_injection5 + inject_time}'
end_injection6 = '${fparse start_injection6 + inject_time}'
end_injection7 = '${fparse start_injection7 + inject_time}'
end_injection8 = '${fparse start_injection8 + inject_time}'
end_injection9 = '${fparse start_injection9 + inject_time}'
end_injection10 = '${fparse start_injection10 + inject_time}'
start_production1 = '${fparse end_injection1 + store_time}'
start_production2 = '${fparse end_injection2 + store_time}'
start_production3 = '${fparse end_injection3 + store_time}'
start_production4 = '${fparse end_injection4 + store_time}'
start_production5 = '${fparse end_injection5 + store_time}'
start_production6 = '${fparse end_injection6 + store_time}'
start_production7 = '${fparse end_injection7 + store_time}'
start_production8 = '${fparse end_injection8 + store_time}'
start_production9 = '${fparse end_injection9 + store_time}'
start_production10 = '${fparse end_injection10 + store_time}'
end_production1 = '${fparse start_production1 + produce_time}'
end_production2 = '${fparse start_production2 + produce_time}'
end_production3 = '${fparse start_production3 + produce_time}'
end_production4 = '${fparse start_production4 + produce_time}'
end_production5 = '${fparse start_production5 + produce_time}'
end_production6 = '${fparse start_production6 + produce_time}'
end_production7 = '${fparse start_production7 + produce_time}'
end_production8 = '${fparse start_production8 + produce_time}'
end_production9 = '${fparse start_production9 + produce_time}'
end_production10 = '${fparse start_production10 + produce_time}'
synctimes = '${start_injection1} ${end_injection1} ${start_production1} ${end_production1}
             ${start_injection2} ${end_injection2} ${start_production2} ${end_production2}
             ${start_injection3} ${end_injection3} ${start_production3} ${end_production3}
             ${start_injection4} ${end_injection4} ${start_production4} ${end_production4}
             ${start_injection5} ${end_injection5} ${start_production5} ${end_production5}
             ${start_injection6} ${end_injection6} ${start_production6} ${end_production6}
             ${start_injection7} ${end_injection7} ${start_production7} ${end_production7}
             ${start_injection8} ${end_injection8} ${start_production8} ${end_production8}
             ${start_injection9} ${end_injection9} ${start_production9} ${end_production9}
             ${start_injection10} ${end_injection10} ${start_production10} ${end_production10}'
#####################################
# Geometry in RZ coordinates
# borehole radius (m)
bh_r = 0.1
# model radius (m)
max_r = 1000
# aquifer thickness (m)
aq_thickness = 20
# cap thickness (m)
cap_thickness = 40
# injection region top and bottom (m).  Note, the mesh is created with the aquifer in y = (-0.5 * aq_thickness, 0.5 * aq_thickness), irrespective of depth (depth only sets the insitu porepressure and temperature)
screen_top = '${fparse 0.5 * aq_thickness}'
screen_bottom = '${fparse -0.5 * aq_thickness}'
# number of elements in radial direction
num_r = 25
# number of elements across half height of aquifer
num_y_aq = 10
# number of elements across height of cap
num_y_cap = 8
# mesh bias in radial direction
bias_r = 1.22
# mesh bias in vertical direction in aquifer top
bias_y_aq_top = 0.9
# mesh bias in vertical direction in cap top
bias_y_cap_top = 1.3
# mesh bias in vertical direction in aquifer bottom
bias_y_aq_bottom = '${fparse 1.0 / bias_y_aq_top}'
# mesh bias in vertical direction in cap bottom
bias_y_cap_bottom = '${fparse 1.0 / bias_y_cap_top}'
depth_centre = '${fparse depth + aq_thickness/2}'
#####################################
# temperature at ground surface (degC)
temp0 = 20
# Vertical geothermal gradient (K/m).  A positive number means temperature increases downwards.
geothermal_gradient = 20E-3
#####################################
# Gravity
gravity = -9.81
#####################################
half_aq_thickness = '${fparse aq_thickness * 0.5}'
half_height = '${fparse half_aq_thickness + cap_thickness}'
approx_screen_length = '${fparse screen_top - screen_bottom}'
# Thermal radius (note this is not strictly correct, it should use the bulk specific heat
#  capacity as defined below, but it doesn't matter here because this is purely for
#  defining the region of refined mesh)
th_r = '${fparse sqrt(inject_fluid_mass / 1000 * 4.12e6 / (approx_screen_length * 3.1416 * aq_specific_heat_cap * aq_density))}'
# radius of fine mesh
fine_r = '${fparse th_r * 2}'
bias_r_fine = 1
num_r_fine = '${fparse int(fine_r/1)}'
######################################
# aquifer properties
aq_porosity = 0.25
aq_hor_perm = 1E-11 # m^2
aq_ver_perm = 2E-12 # m^2
aq_density = 2650 # kg/m^3
aq_specific_heat_cap = 800 # J/Kg/K
aq_hor_thermal_cond = 3 # W/m/K
aq_ver_thermal_cond = 3 # W/m/K
aq_disp_parallel = 0 # m
aq_disp_perp = 0 # m
# Bulk volumetric heat capacity of aquifer:
aq_vol_cp = '${fparse aq_specific_heat_cap * aq_density * (1 - aq_porosity) + 4180 * 1000 * aq_porosity}'
# Thermal radius (correct version using bulk cp):
R_th = '${fparse sqrt(inject_fluid_mass * 4180 / (approx_screen_length * 3.1416 * aq_vol_cp))}'
aq_lambda_eff_hor = '${fparse aq_hor_thermal_cond + 0.3 * aq_disp_parallel * R_th * aq_vol_cp / (inject_time * 60 * 60 * 24)}'
aq_lambda_eff_ver = '${fparse aq_ver_thermal_cond + 0.3 * aq_disp_perp * R_th * aq_vol_cp / (inject_time * 60 * 60 * 24)}'
aq_hor_dry_thermal_cond = '${fparse aq_lambda_eff_hor * 60 * 60 * 24}' # J/day/m/K
aq_ver_dry_thermal_cond = '${fparse aq_lambda_eff_ver * 60 * 60 * 24}' # J/day/m/K
aq_hor_wet_thermal_cond = '${fparse aq_lambda_eff_hor * 60 * 60 * 24}' # J/day/m/K
aq_ver_wet_thermal_cond = '${fparse aq_lambda_eff_ver * 60 * 60 * 24}' # J/day/m/K
# cap-rock properties
cap_porosity = 0.25
cap_hor_perm = 1E-16 # m^2
cap_ver_perm = 1E-17 # m^2
cap_density = 2650 # kg/m^3
cap_specific_heat_cap = 800 # J/kg/K
cap_hor_thermal_cond = 3 # W/m/K
cap_ver_thermal_cond = 3 # W/m/K
cap_hor_dry_thermal_cond = '${fparse cap_hor_thermal_cond * 60 * 60 * 24}' # J/day/m/K
cap_ver_dry_thermal_cond = '${fparse cap_ver_thermal_cond * 60 * 60 * 24}' # J/day/m/K
cap_hor_wet_thermal_cond = '${fparse cap_hor_thermal_cond * 60 * 60 * 24}' # J/day/m/K
cap_ver_wet_thermal_cond = '${fparse cap_ver_thermal_cond * 60 * 60 * 24}' # J/day/m/K
######################################
[Mesh]
  coord_type = RZ
  [aq_top_fine]
    type = GeneratedMeshGenerator
    dim = 2
    nx = ${num_r_fine}
    xmin = ${bh_r}
    xmax = ${fine_r}
    bias_x = ${bias_r_fine}
    bias_y = ${bias_y_aq_top}
    ny = ${num_y_aq}
    ymin = 0
    ymax = ${half_aq_thickness}
  []
  [cap_top_fine]
    type = GeneratedMeshGenerator
    dim = 2
    nx = ${num_r_fine}
    xmin = ${bh_r}
    xmax = ${fine_r}
    bias_x = ${bias_r_fine}
    bias_y = ${bias_y_cap_top}
    ny = ${num_y_cap}
    ymax = ${half_height}
    ymin = ${half_aq_thickness}
  []
  [aq_and_cap_top_fine]
    type = StitchedMeshGenerator
    inputs = 'aq_top_fine cap_top_fine'
    clear_stitched_boundary_ids = true
    stitch_boundaries_pairs = 'top bottom'
  []
  [aq_bottom_fine]
    type = GeneratedMeshGenerator
    dim = 2
    nx = ${num_r_fine}
    xmin = ${bh_r}
    xmax = ${fine_r}
    bias_x = ${bias_r_fine}
    bias_y = ${bias_y_aq_bottom}
    ny = ${num_y_aq}
    ymax = 0
    ymin = -${half_aq_thickness}
  []
  [cap_bottom_fine]
    type = GeneratedMeshGenerator
    dim = 2
    nx = ${num_r_fine}
    xmin = ${bh_r}
    xmax = ${fine_r}
    bias_x = ${bias_r_fine}
    bias_y = ${bias_y_cap_bottom}
    ny = ${num_y_cap}
    ymin = -${half_height}
    ymax = -${half_aq_thickness}
  []
  [aq_and_cap_bottom_fine]
    type = StitchedMeshGenerator
    inputs = 'aq_bottom_fine cap_bottom_fine'
    clear_stitched_boundary_ids = true
    stitch_boundaries_pairs = 'bottom top'
    merge_boundaries_with_same_name = false
  []
  [aq_and_cap_fine]
    type = StitchedMeshGenerator
    inputs = 'aq_and_cap_bottom_fine aq_and_cap_top_fine'
    clear_stitched_boundary_ids = true
    stitch_boundaries_pairs = 'top bottom'
  []
  [aq_top]
    type = GeneratedMeshGenerator
    dim = 2
    nx = ${num_r}
    xmin = ${fine_r}
    xmax = ${max_r}
    bias_x = ${bias_r}
    bias_y = ${bias_y_aq_top}
    ny = ${num_y_aq}
    ymin = 0
    ymax = ${half_aq_thickness}
  []
  [cap_top]
    type = GeneratedMeshGenerator
    dim = 2
    nx = ${num_r}
    xmin = ${fine_r}
    xmax = ${max_r}
    bias_x = ${bias_r}
    bias_y = ${bias_y_cap_top}
    ny = ${num_y_cap}
    ymax = ${half_height}
    ymin = ${half_aq_thickness}
  []
  [aq_and_cap_top]
    type = StitchedMeshGenerator
    inputs = 'aq_top cap_top'
    clear_stitched_boundary_ids = true
    stitch_boundaries_pairs = 'top bottom'
  []
  [aq_bottom]
    type = GeneratedMeshGenerator
    dim = 2
    nx = ${num_r}
    xmin = ${fine_r}
    xmax = ${max_r}
    bias_x = ${bias_r}
    bias_y = ${bias_y_aq_bottom}
    ny = ${num_y_aq}
    ymax = 0
    ymin = -${half_aq_thickness}
  []
  [cap_bottom]
    type = GeneratedMeshGenerator
    dim = 2
    nx = ${num_r}
    xmin = ${fine_r}
    xmax = ${max_r}
    bias_x = ${bias_r}
    bias_y = ${bias_y_cap_bottom}
    ny = ${num_y_cap}
    ymin = -${half_height}
    ymax = -${half_aq_thickness}
  []
  [aq_and_cap_bottom]
    type = StitchedMeshGenerator
    inputs = 'aq_bottom cap_bottom'
    clear_stitched_boundary_ids = true
    stitch_boundaries_pairs = 'bottom top'
  []
  [aq_and_cap]
    type = StitchedMeshGenerator
    inputs = 'aq_and_cap_bottom aq_and_cap_top'
    clear_stitched_boundary_ids = true
    stitch_boundaries_pairs = 'top bottom'
  []
  [aq_and_cap_all]
    type = StitchedMeshGenerator
    inputs = 'aq_and_cap_fine aq_and_cap'
    clear_stitched_boundary_ids = true
    stitch_boundaries_pairs = 'right left'
  []
  [aquifer]
    type = ParsedSubdomainMeshGenerator
    input = aq_and_cap_all
    combinatorial_geometry = 'y >= -${half_aq_thickness} & y <= ${half_aq_thickness}'
    block_id = 1
  []
  [top_cap]
    type = ParsedSubdomainMeshGenerator
    input = aquifer
    combinatorial_geometry = 'y >= ${half_aq_thickness}'
    block_id = 2
  []
  [bottom_cap]
    type = ParsedSubdomainMeshGenerator
    input = top_cap
    combinatorial_geometry = 'y <= -${half_aq_thickness}'
    block_id = 3
  []
  [injection_area]
    type = ParsedGenerateSideset
    combinatorial_geometry = 'x<=${bh_r}*1.000001 & y >= ${screen_bottom} & y <= ${screen_top}'
    included_subdomains = 1
    new_sideset_name = 'injection_area'
    input = 'bottom_cap'
  []
  [rename]
    type = RenameBlockGenerator
    old_block = '1 2 3'
    new_block = 'aquifer caps caps'
    input = 'injection_area'
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 ${gravity} 0'
[]
[Variables]
  [porepressure]
  []
  [temperature]
    scaling = 1E-5
  []
[]
[PorousFlowFullySaturated]
  coupling_type = ThermoHydro
  porepressure = porepressure
  temperature = temperature
  fp = tabulated_water
  stabilization = KT
  flux_limiter_type = ${flux_limiter}
  use_displaced_mesh = false
  temperature_unit = Celsius
  pressure_unit = Pa
  time_unit = days
[]
[ICs]
  [porepressure]
    type = FunctionIC
    variable = porepressure
    function = insitu_pressure
  []
  [temperature]
    type = FunctionIC
    variable = temperature
    function = insitu_temperature
  []
[]
[BCs]
  [outer_boundary_porepressure]
    type = FunctionDirichletBC
    preset = true
    variable = porepressure
    function = insitu_pressure
    boundary = 'bottom right top'
  []
  [outer_boundary_temperature]
    type = FunctionDirichletBC
    preset = true
    variable = temperature
    function = insitu_temperature
    boundary = 'bottom right top'
  []
  [inject_heat]
    type = FunctionDirichletBC
    variable = temperature
    function = ${inject_temp}
    boundary = 'injection_area'
  []
  [inject_fluid]
    type = PorousFlowSink
    variable = porepressure
    boundary = injection_area
    flux_function = injection_rate_value
  []
  [produce_heat]
    type = PorousFlowSink
    variable = temperature
    boundary = injection_area
    flux_function = production_rate_value
    fluid_phase = 0
    use_enthalpy = true
    save_in = heat_flux_out
  []
  [produce_fluid]
    type = PorousFlowSink
    variable = porepressure
    boundary = injection_area
    flux_function = production_rate_value
  []
[]
[Controls]
  [inject_on]
    type = ConditionalFunctionEnableControl
    enable_objects = 'BCs::inject_heat BCs::inject_fluid'
    conditional_function = inject
    implicit = false
    execute_on = 'initial timestep_begin'
  []
  [produce_on]
    type = ConditionalFunctionEnableControl
    enable_objects = 'BCs::produce_heat BCs::produce_fluid'
    conditional_function = produce
    implicit = false
    execute_on = 'initial timestep_begin'
  []
[]
[Functions]
  [insitu_pressure]
    type = ParsedFunction
    expression = '(y - ${depth_centre}) * 1000 * ${gravity} + 1E5' # approx insitu pressure in Pa
  []
  [insitu_temperature]
    type = ParsedFunction
    expression = '${temp0} + (${depth_centre} - y) * ${geothermal_gradient}'
  []
  [inject]
    type = ParsedFunction
    expression = 'if(t >= ${start_injection1} & t < ${end_injection1}, 1,
             if(t >= ${start_injection2} & t < ${end_injection2}, 1,
             if(t >= ${start_injection3} & t < ${end_injection3}, 1,
             if(t >= ${start_injection4} & t < ${end_injection4}, 1,
             if(t >= ${start_injection5} & t < ${end_injection5}, 1,
             if(t >= ${start_injection6} & t < ${end_injection6}, 1,
             if(t >= ${start_injection7} & t < ${end_injection7}, 1,
             if(t >= ${start_injection8} & t < ${end_injection8}, 1,
             if(t >= ${start_injection9} & t < ${end_injection9}, 1,
             if(t >= ${start_injection10} & t < ${end_injection10}, 1, 0))))))))))'
  []
  [produce]
    type = ParsedFunction
    expression = 'if(t >= ${start_production1} & t < ${end_production1}, 1,
             if(t >= ${start_production2} & t < ${end_production2}, 1,
             if(t >= ${start_production3} & t < ${end_production3}, 1,
             if(t >= ${start_production4} & t < ${end_production4}, 1,
             if(t >= ${start_production5} & t < ${end_production5}, 1,
             if(t >= ${start_production6} & t < ${end_production6}, 1,
             if(t >= ${start_production7} & t < ${end_production7}, 1,
             if(t >= ${start_production8} & t < ${end_production8}, 1,
             if(t >= ${start_production9} & t < ${end_production9}, 1,
             if(t >= ${start_production10} & t < ${end_production10}, 1, 0))))))))))'
  []
  [injection_rate_value]
    type = ParsedFunction
    symbol_names = true_screen_area
    symbol_values = true_screen_area
    expression = '-${inject_fluid_mass}/(true_screen_area * ${inject_time})'
  []
  [production_rate_value]
    type = ParsedFunction
    symbol_names = true_screen_area
    symbol_values = true_screen_area
    expression = '${produce_fluid_mass}/(true_screen_area * ${produce_time})'
  []
  [heat_out_in_timestep]
    type = ParsedFunction
    symbol_names = 'dt heat_out'
    symbol_values = 'dt heat_out_fromBC'
    expression = 'dt*heat_out'
  []
  [produced_T_time_integrated]
    type = ParsedFunction
    symbol_names = 'dt produced_T'
    symbol_values = 'dt produced_T'
    expression = 'dt*produced_T / ${produce_time}'
  []
[]
[AuxVariables]
  [density]
    family = MONOMIAL
    order = CONSTANT
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
  [heat_flux_out]
    outputs = none
  []
[]
[AuxKernels]
  [density]
    type = PorousFlowPropertyAux
    variable = density
    property = density
  []
  [porosity]
    type = PorousFlowPropertyAux
    variable = porosity
    property = porosity
  []
[]
[FluidProperties]
  [true_water]
    type = Water97FluidProperties
  []
  [tabulated_water]
    type = TabulatedFluidProperties
    fp = true_water
    temperature_min = 275 # K
    temperature_max = 600
    interpolated_properties = 'density viscosity enthalpy internal_energy'
    fluid_property_output_file = water97_tabulated_modified.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = water97_tabulated_modified.csv
  []
[]
[Materials]
  [porosity_aq]
    type = PorousFlowPorosityConst
    porosity = ${aq_porosity}
    block = aquifer
  []
  [porosity_caps]
    type = PorousFlowPorosityConst
    porosity = ${cap_porosity}
    block = caps
  []
  [permeability_aquifer]
    type = PorousFlowPermeabilityConst
    block = aquifer
    permeability = '${aq_hor_perm} 0 0   0 ${aq_ver_perm} 0   0 0 0'
  []
  [permeability_caps]
    type = PorousFlowPermeabilityConst
    block = caps
    permeability = '${cap_hor_perm} 0 0   0 ${cap_ver_perm} 0   0 0 0'
  []
  [aq_internal_energy]
    type = PorousFlowMatrixInternalEnergy
    block = aquifer
    density = ${aq_density}
    specific_heat_capacity = ${aq_specific_heat_cap}
  []
  [caps_internal_energy]
    type = PorousFlowMatrixInternalEnergy
    block = caps
    density = ${cap_density}
    specific_heat_capacity = ${cap_specific_heat_cap}
  []
  [aq_thermal_conductivity]
    type = PorousFlowThermalConductivityIdeal
    block = aquifer
    dry_thermal_conductivity = '${aq_hor_dry_thermal_cond} 0 0  0 ${aq_ver_dry_thermal_cond} 0  0 0 0'
    wet_thermal_conductivity = '${aq_hor_wet_thermal_cond} 0 0  0 ${aq_ver_wet_thermal_cond} 0  0 0 0'
  []
  [caps_thermal_conductivity]
    type = PorousFlowThermalConductivityIdeal
    block = caps
    dry_thermal_conductivity = '${cap_hor_dry_thermal_cond} 0 0  0 ${cap_ver_dry_thermal_cond} 0  0 0 0'
    wet_thermal_conductivity = '${cap_hor_wet_thermal_cond} 0 0  0 ${cap_ver_wet_thermal_cond} 0  0 0 0'
  []
[]
[Postprocessors]
  [true_screen_area] # this accounts for meshes that do not match screen_top and screen_bottom exactly
    type = AreaPostprocessor
    boundary = injection_area
    execute_on = 'initial'
    outputs = 'none'
  []
  [dt]
    type = TimestepSize
  []
  [heat_out_fromBC]
    type = NodalSum
    variable = heat_flux_out
    boundary = injection_area
    execute_on = 'initial timestep_end'
    outputs = 'none'
  []
  [heat_out_per_timestep]
    type = FunctionValuePostprocessor
    function = heat_out_in_timestep
    execute_on = 'timestep_end'
    outputs = 'none'
  []
  [heat_out_cumulative]
    type = CumulativeValuePostprocessor
    postprocessor = heat_out_per_timestep
    execute_on = 'timestep_end'
    outputs = 'csv console'
  []
  [produced_T]
    type = SideAverageValue
    boundary = injection_area
    variable = temperature
    execute_on = 'initial timestep_end'
    outputs = 'csv console'
  []
  [produced_T_time_integrated]
    type = FunctionValuePostprocessor
    function = produced_T_time_integrated
    execute_on = 'timestep_end'
    outputs = 'none'
  []
  [produced_T_cumulative]
    type = CumulativeValuePostprocessor
    postprocessor = produced_T_time_integrated
    execute_on = 'timestep_end'
    outputs = 'csv console'
  []
[]
[Preconditioning]
  [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'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = ${end_simulation}
  timestep_tolerance = 1e-5
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1e-3
    growth_factor = 2
  []
  dtmax = 1
  dtmin = 1e-5
  # rough calc for fluid, |R| ~ V*k*1E6 ~ V*1E-5
  # rough calc for heat, |R| ~ V*(lam*1E-3 + h*1E-5)  ~ V*(1E3 + 1E-2)
  # so scale heat by 1E-7 and go for nl_abs_tol = 1E-4, which should give a max error of
  # ~1Pa and ~0.1K in the first metre around the borehole
  nl_abs_tol = 1E-4
  nl_rel_tol = 1E-5
[]
[Outputs]
  sync_times = ${synctimes}
  [ex]
    type = Exodus
    time_step_interval = 20
  []
  [csv]
    type = CSV
    execute_postprocessors_on = 'initial timestep_end'
  []
[]
(modules/porous_flow/examples/tutorial/08.i)
# Unsaturated Darcy-Richards flow
[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]
  []
[]
[PorousFlowUnsaturated]
  porepressure = porepressure
  coupling_type = Hydro
  gravity = '0 0 0'
  fp = the_simple_fluid
  relative_permeability_exponent = 3
  relative_permeability_type = Corey
  residual_saturation = 0.1
  van_genuchten_alpha = 1E-6
  van_genuchten_m = 0.6
[]
[BCs]
  [production]
    type = PorousFlowSink
    variable = porepressure
    fluid_phase = 0
    flux_function = 1E-2
    use_relperm = true
    boundary = injection_area
  []
[]
[FluidProperties]
  [the_simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2E9
    viscosity = 1.0E-3
    density0 = 1000.0
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [permeability_aquifer]
    type = PorousFlowPermeabilityConst
    block = aquifer
    permeability = '1E-14 0 0   0 1E-14 0   0 0 1E-14'
  []
  [permeability_caps]
    type = PorousFlowPermeabilityConst
    block = caps
    permeability = '1E-15 0 0   0 1E-15 0   0 0 1E-16'
  []
[]
[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-12
  nl_rel_tol = 1e-12
[]
[Outputs]
  exodus = true
[]
(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/examples/tutorial/10.i)
# Unsaturated Darcy-Richards flow without using an Action
[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'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = pp
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    alpha = 1E-6
    m = 0.6
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Variables]
  [pp]
  []
[]
[Kernels]
  [time_derivative]
    type = PorousFlowMassTimeDerivative
    variable = pp
  []
  [flux]
    type = PorousFlowAdvectiveFlux
    variable = pp
    gravity = '0 0 0'
  []
[]
[AuxVariables]
  [sat]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [saturation]
    type = PorousFlowPropertyAux
    variable = sat
    property = saturation
  []
[]
[BCs]
  [production]
    type = PorousFlowSink
    variable = pp
    fluid_phase = 0
    flux_function = 1E-2
    use_relperm = true
    boundary = injection_area
  []
[]
[FluidProperties]
  [the_simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2E9
    viscosity = 1.0E-3
    density0 = 1000.0
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [permeability_aquifer]
    type = PorousFlowPermeabilityConst
    block = aquifer
    permeability = '1E-14 0 0   0 1E-14 0   0 0 1E-14'
  []
  [permeability_caps]
    type = PorousFlowPermeabilityConst
    block = caps
    permeability = '1E-15 0 0   0 1E-15 0   0 0 1E-16'
  []
  [saturation_calculator]
    type = PorousFlow1PhaseP
    porepressure = pp
    capillary_pressure = pc
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = 293
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = the_simple_fluid
    phase = 0
  []
  [relperm]
    type = PorousFlowRelativePermeabilityCorey
    n = 3
    s_res = 0.1
    sum_s_res = 0.1
    phase = 0
  []
[]
[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_rel_tol = 1E-12
  nl_abs_tol = 1e-10
[]
[Outputs]
  exodus = true
[]
(modules/porous_flow/examples/tutorial/11_2D.i)
# Two-phase borehole injection problem in RZ coordinates
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    nx = 10
    xmin = 1.0
    xmax = 10
    bias_x = 1.4
    ny = 3
    ymin = -6
    ymax = 6
  []
  [aquifer]
    input = gen
    type = SubdomainBoundingBoxGenerator
    block_id = 1
    bottom_left = '0 -2 0'
    top_right = '10 2 0'
  []
  [injection_area]
    type = ParsedGenerateSideset
    combinatorial_geometry = 'x<1.0001'
    included_subdomains = 1
    new_sideset_name = 'injection_area'
    input = 'aquifer'
  []
  [rename]
    type = RenameBlockGenerator
    old_block = '0 1'
    new_block = 'caps aquifer'
    input = 'injection_area'
  []
  coord_type = RZ
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pwater pgas T disp_r'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    alpha = 1E-6
    m = 0.6
  []
[]
[GlobalParams]
  displacements = 'disp_r disp_z'
  gravity = '0 0 0'
  biot_coefficient = 1.0
  PorousFlowDictator = dictator
[]
[Variables]
  [pwater]
    initial_condition = 20E6
  []
  [pgas]
    initial_condition = 20.1E6
  []
  [T]
    initial_condition = 330
    scaling = 1E-5
  []
  [disp_r]
    scaling = 1E-5
  []
[]
[Kernels]
  [mass_water_dot]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pwater
  []
  [flux_water]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    use_displaced_mesh = false
    variable = pwater
  []
  [vol_strain_rate_water]
    type = PorousFlowMassVolumetricExpansion
    fluid_component = 0
    variable = pwater
  []
  [mass_co2_dot]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = pgas
  []
  [flux_co2]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    use_displaced_mesh = false
    variable = pgas
  []
  [vol_strain_rate_co2]
    type = PorousFlowMassVolumetricExpansion
    fluid_component = 1
    variable = pgas
  []
  [energy_dot]
    type = PorousFlowEnergyTimeDerivative
    variable = T
  []
  [advection]
    type = PorousFlowHeatAdvection
    use_displaced_mesh = false
    variable = T
  []
  [conduction]
    type = PorousFlowHeatConduction
    use_displaced_mesh = false
    variable = T
  []
  [vol_strain_rate_heat]
    type = PorousFlowHeatVolumetricExpansion
    variable = T
  []
  [grad_stress_r]
    type = StressDivergenceRZTensors
    temperature = T
    variable = disp_r
    eigenstrain_names = thermal_contribution
    use_displaced_mesh = false
    component = 0
  []
  [poro_r]
    type = PorousFlowEffectiveStressCoupling
    variable = disp_r
    use_displaced_mesh = false
    component = 0
  []
[]
[AuxVariables]
  [disp_z]
  []
  [effective_fluid_pressure]
    family = MONOMIAL
    order = CONSTANT
  []
  [mass_frac_phase0_species0]
    initial_condition = 1 # all water in phase=0
  []
  [mass_frac_phase1_species0]
    initial_condition = 0 # no water in phase=1
  []
  [sgas]
    family = MONOMIAL
    order = CONSTANT
  []
  [swater]
    family = MONOMIAL
    order = CONSTANT
  []
  [stress_rr]
    family = MONOMIAL
    order = CONSTANT
  []
  [stress_tt]
    family = MONOMIAL
    order = CONSTANT
  []
  [stress_zz]
    family = MONOMIAL
    order = CONSTANT
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [effective_fluid_pressure]
    type = ParsedAux
    coupled_variables = 'pwater pgas swater sgas'
    expression = 'pwater * swater + pgas * sgas'
    variable = effective_fluid_pressure
  []
  [swater]
    type = PorousFlowPropertyAux
    variable = swater
    property = saturation
    phase = 0
    execute_on = timestep_end
  []
  [sgas]
    type = PorousFlowPropertyAux
    variable = sgas
    property = saturation
    phase = 1
    execute_on = timestep_end
  []
  [stress_rr_aux]
    type = RankTwoAux
    variable = stress_rr
    rank_two_tensor = stress
    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
  []
  [porosity]
    type = PorousFlowPropertyAux
    variable = porosity
    property = porosity
    execute_on = timestep_end
  []
[]
[BCs]
  [pinned_top_bottom_r]
    type = DirichletBC
    variable = disp_r
    value = 0
    boundary = 'top bottom'
  []
  [cavity_pressure_r]
    type = Pressure
    boundary = injection_area
    variable = disp_r
    postprocessor = constrained_effective_fluid_pressure_at_wellbore
    use_displaced_mesh = false
  []
  [cold_co2]
    type = DirichletBC
    boundary = injection_area
    variable = T
    value = 290 # injection temperature
    use_displaced_mesh = false
  []
  [constant_co2_injection]
    type = PorousFlowSink
    boundary = injection_area
    variable = pgas
    fluid_phase = 1
    flux_function = -1E-4
    use_displaced_mesh = false
  []
  [outer_water_removal]
    type = PorousFlowPiecewiseLinearSink
    boundary = right
    variable = pwater
    fluid_phase = 0
    pt_vals = '0 1E9'
    multipliers = '0 1E8'
    PT_shift = 20E6
    use_mobility = true
    use_relperm = true
    use_displaced_mesh = false
  []
  [outer_co2_removal]
    type = PorousFlowPiecewiseLinearSink
    boundary = right
    variable = pgas
    fluid_phase = 1
    pt_vals = '0 1E9'
    multipliers = '0 1E8'
    PT_shift = 20.1E6
    use_mobility = true
    use_relperm = true
    use_displaced_mesh = false
  []
[]
[FluidProperties]
  [true_water]
    type = Water97FluidProperties
  []
  [tabulated_water]
    type = TabulatedBicubicFluidProperties
    fp = true_water
    temperature_min = 275
    pressure_max = 1E8
    fluid_property_output_file = water97_tabulated_11.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = water97_tabulated_11.csv
  []
  [true_co2]
    type = CO2FluidProperties
  []
  [tabulated_co2]
    type = TabulatedBicubicFluidProperties
    fp = true_co2
    temperature_min = 275
    pressure_max = 1E8
    fluid_property_output_file = co2_tabulated_11.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = co2_tabulated_11.csv
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = T
  []
  [saturation_calculator]
    type = PorousFlow2PhasePP
    phase0_porepressure = pwater
    phase1_porepressure = pgas
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'mass_frac_phase0_species0 mass_frac_phase1_species0'
  []
  [water]
    type = PorousFlowSingleComponentFluid
    fp = tabulated_water
    phase = 0
  []
  [co2]
    type = PorousFlowSingleComponentFluid
    fp = tabulated_co2
    phase = 1
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 4
    s_res = 0.1
    sum_s_res = 0.2
    phase = 0
  []
  [relperm_co2]
    type = PorousFlowRelativePermeabilityBC
    nw_phase = true
    lambda = 2
    s_res = 0.1
    sum_s_res = 0.2
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosity
    fluid = true
    mechanical = true
    thermal = true
    porosity_zero = 0.1
    reference_temperature = 330
    reference_porepressure = 20E6
    thermal_expansion_coeff = 15E-6 # volumetric
    solid_bulk = 8E9 # unimportant since biot = 1
  []
  [permeability_aquifer]
    type = PorousFlowPermeabilityKozenyCarman
    block = aquifer
    poroperm_function = kozeny_carman_phi0
    phi0 = 0.1
    n = 2
    m = 2
    k0 = 1E-12
  []
  [permeability_caps]
    type = PorousFlowPermeabilityKozenyCarman
    block = caps
    poroperm_function = kozeny_carman_phi0
    phi0 = 0.1
    n = 2
    m = 2
    k0 = 1E-15
    k_anisotropy = '1 0 0  0 1 0  0 0 0.1'
  []
  [rock_thermal_conductivity]
    type = PorousFlowThermalConductivityIdeal
    dry_thermal_conductivity = '2 0 0  0 2 0  0 0 2'
  []
  [rock_internal_energy]
    type = PorousFlowMatrixInternalEnergy
    specific_heat_capacity = 1100
    density = 2300
  []
  [elasticity_tensor]
    type = ComputeIsotropicElasticityTensor
    youngs_modulus = 5E9
    poissons_ratio = 0.0
  []
  [strain]
    type = ComputeAxisymmetricRZSmallStrain
    eigenstrain_names = 'thermal_contribution initial_stress'
  []
  [thermal_contribution]
    type = ComputeThermalExpansionEigenstrain
    temperature = T
    thermal_expansion_coeff = 5E-6 # this is the linear thermal expansion coefficient
    eigenstrain_name = thermal_contribution
    stress_free_temperature = 330
  []
  [initial_strain]
    type = ComputeEigenstrainFromInitialStress
    initial_stress = '20E6 0 0  0 20E6 0  0 0 20E6'
    eigenstrain_name = initial_stress
  []
  [stress]
    type = ComputeLinearElasticStress
  []
  [effective_fluid_pressure]
    type = PorousFlowEffectiveFluidPressure
  []
  [volumetric_strain]
    type = PorousFlowVolumetricStrain
  []
[]
[Postprocessors]
  [effective_fluid_pressure_at_wellbore]
    type = PointValue
    variable = effective_fluid_pressure
    point = '1 0 0'
    execute_on = timestep_begin
    use_displaced_mesh = false
  []
  [constrained_effective_fluid_pressure_at_wellbore]
    type = FunctionValuePostprocessor
    function = constrain_effective_fluid_pressure
    execute_on = timestep_begin
  []
[]
[Functions]
  [constrain_effective_fluid_pressure]
    type = ParsedFunction
    symbol_names = effective_fluid_pressure_at_wellbore
    symbol_values = effective_fluid_pressure_at_wellbore
    expression = 'max(effective_fluid_pressure_at_wellbore, 20E6)'
  []
[]
[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 = 1E3
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1E3
    growth_factor = 1.2
    optimal_iterations = 10
  []
  nl_abs_tol = 1E-7
[]
[Outputs]
  exodus = true
[]
(modules/porous_flow/test/tests/fluidstate/theis_brineco2_nonisothermal.i)
# Two phase nonisothermal Theis problem: Flow from single source.
# Constant rate injection 2 kg/s of cold CO2 into warm reservoir
# 1D cylindrical mesh
# Initially, system has only a liquid phase, until enough gas is injected
# to form a gas phase, in which case the system becomes two phase.
[Mesh]
  [mesh]
    type = GeneratedMeshGenerator
    dim = 1
    nx = 40
    xmin = 0.1
    xmax = 200
    bias_x = 1.05
  []
  coord_type = RZ
  rz_coord_axis = Y
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[AuxVariables]
  [saturation_gas]
    order = CONSTANT
    family = MONOMIAL
  []
  [x1]
    order = CONSTANT
    family = MONOMIAL
  []
  [y0]
    order = CONSTANT
    family = MONOMIAL
  []
[]
[AuxKernels]
  [saturation_gas]
    type = PorousFlowPropertyAux
    variable = saturation_gas
    property = saturation
    phase = 1
    execute_on = timestep_end
  []
  [x1]
    type = PorousFlowPropertyAux
    variable = x1
    property = mass_fraction
    phase = 0
    fluid_component = 1
    execute_on = timestep_end
  []
  [y0]
    type = PorousFlowPropertyAux
    variable = y0
    property = mass_fraction
    phase = 1
    fluid_component = 0
    execute_on = timestep_end
  []
[]
[Variables]
  [pgas]
    initial_condition = 20e6
  []
  [zi]
    initial_condition = 0
  []
  [xnacl]
    initial_condition = 0.1
  []
  [temperature]
    initial_condition = 70
    scaling = 1e-4
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pgas
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pgas
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = zi
  []
  [flux1]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    variable = zi
  []
  [mass2]
    type = PorousFlowMassTimeDerivative
    fluid_component = 2
    variable = xnacl
  []
  [flux2]
    type = PorousFlowAdvectiveFlux
    fluid_component = 2
    variable = xnacl
  []
  [energy]
    type = PorousFlowEnergyTimeDerivative
    variable = temperature
  []
  [heatadv]
    type = PorousFlowHeatAdvection
    variable = temperature
  []
  [conduction]
    type = PorousFlowHeatConduction
    variable = temperature
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pgas zi xnacl temperature'
    number_fluid_phases = 2
    number_fluid_components = 3
  []
  [pc]
    type = PorousFlowCapillaryPressureConst
    pc = 0
  []
  [fs]
    type = PorousFlowBrineCO2
    brine_fp = brine
    co2_fp = co2
    capillary_pressure = pc
  []
[]
[FluidProperties]
  [co2]
    type = CO2FluidProperties
  []
  [brine]
    type = BrineFluidProperties
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = temperature
  []
  [brineco2]
    type = PorousFlowFluidState
    gas_porepressure = pgas
    z = zi
    temperature = temperature
    temperature_unit = Celsius
    xnacl = xnacl
    capillary_pressure = pc
    fluid_state = fs
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.2
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1e-12 0 0 0 1e-12 0 0 0 1e-12'
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
    s_res = 0.1
    sum_s_res = 0.1
  []
  [relperm_gas]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 1
  []
  [rockheat]
    type = PorousFlowMatrixInternalEnergy
    specific_heat_capacity = 1000
    density = 2500
  []
  [rock_thermal_conductivity]
    type = PorousFlowThermalConductivityIdeal
    dry_thermal_conductivity = '50 0 0  0 50 0  0 0 50'
  []
[]
[BCs]
  [cold_gas]
    type = DirichletBC
    boundary = left
    variable = temperature
    value = 20
  []
  [gas_injecton]
    type = PorousFlowSink
    boundary = left
    variable = zi
    flux_function = -0.159155
  []
  [rightwater]
    type = DirichletBC
    boundary = right
    value = 20e6
    variable = pgas
  []
  [righttemp]
    type = DirichletBC
    boundary = right
    value = 70
    variable = temperature
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres      asm      lu           NONZERO                   2'
  []
[]
[Executioner]
  type = Transient
  solve_type = NEWTON
  end_time = 1e4
  nl_abs_tol = 1e-7
  nl_rel_tol = 1e-5
  # Avoids failing first time step in parallel
  line_search = 'none'
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1
    growth_factor = 1.5
  []
[]
[Postprocessors]
  [pgas]
    type = PointValue
    point = '2 0 0'
    variable = pgas
  []
  [sgas]
    type = PointValue
    point = '2 0 0'
    variable = saturation_gas
  []
  [zi]
    type = PointValue
    point = '2 0 0'
    variable = zi
  []
  [temperature]
    type = PointValue
    point = '2 0 0'
    variable = temperature
  []
  [massgas]
    type = PorousFlowFluidMass
    fluid_component = 1
  []
  [x1]
    type = PointValue
    point = '2 0 0'
    variable = x1
  []
  [y0]
    type = PointValue
    point = '2 0 0'
    variable = y0
  []
[]
[Outputs]
  print_linear_residuals = false
  perf_graph = true
  csv = true
[]
(modules/porous_flow/test/tests/sinks/s02.i)
# apply a sink flux with use_mobility=true and observe the correct behavior
[Mesh]
  type = GeneratedMesh
  dim = 3
  nx = 1
  ny = 1
  nz = 1
  xmin = 0
  xmax = 1
  ymin = 0
  ymax = 1
  zmin = 0
  zmax = 2
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp'
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    m = 0.5
    alpha = 1
  []
[]
[Variables]
  [pp]
  []
[]
[ICs]
  [pp]
    type = FunctionIC
    variable = pp
    function = y+1
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pp
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 1.3
    density0 = 1.1
    thermal_expansion = 0
    viscosity = 1.1
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = pp
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '0.2 0 0 0 0.1 0 0 0 0.1'
  []
  [relperm]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
  []
[]
[AuxVariables]
  [flux_out]
  []
  [xval]
  []
  [yval]
  []
[]
[ICs]
  [xval]
    type = FunctionIC
    variable = xval
    function = x
  []
  [yval]
    type = FunctionIC
    variable = yval
    function = y
  []
[]
[Postprocessors]
  [p00]
    type = PointValue
    point = '0 0 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [m00]
    type = ParsedPostprocessor
    expression = 'vol*por*dens0*exp(p00/bulk)'
    constant_names = 'vol por dens0 bulk'
    constant_expressions = '0.25 0.1 1.1 1.3'
    pp_names = 'p00'
    execute_on = 'initial timestep_end'
  []
  [dm00]
    type = ChangeOverTimePostprocessor
    postprocessor = m00
    outputs = none
  []
  [m00_prev]
    type = ParsedPostprocessor
    expression = 'm00 - dm00'
    pp_names = 'm00 dm00'
    outputs = 'console'
  []
  [del_m00]
    type = ParsedPostprocessor
    expression = 'fcn*perm*dens0*exp(p00/bulk)/visc*area*dt'
    constant_names = 'fcn perm dens0 bulk visc area dt'
    constant_expressions = '6   0.2  1.1 1.3  1.1  0.5  1E-3'
    pp_names = 'p00'
    outputs = 'console'
  []
  [m00_expect]
    type = ParsedPostprocessor
    expression = 'm00_prev - del_m00'
    pp_names = 'm00_prev del_m00'
  []
  [p10]
    type = PointValue
    point = '1 0 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [p01]
    type = PointValue
    point = '0 1 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [m01]
    type = ParsedPostprocessor
    expression = 'vol*por*dens0*exp(p01/bulk)'
    constant_names = 'vol por dens0 bulk'
    constant_expressions = '0.25 0.1 1.1 1.3'
    pp_names = 'p01'
    execute_on = 'initial timestep_end'
  []
  [dm01]
    type = ChangeOverTimePostprocessor
    postprocessor = m01
    outputs = none
  []
  [m01_prev]
    type = ParsedPostprocessor
    expression = 'm01 - dm01'
    pp_names = 'm01 dm01'
    outputs = 'console'
  []
  [del_m01]
    type = ParsedPostprocessor
    expression = 'fcn*perm*dens0*exp(p01/bulk)/visc*area*dt'
    constant_names = 'fcn perm dens0 bulk visc area dt'
    constant_expressions = '6   0.2  1.1 1.3  1.1  0.5  1E-3'
    pp_names = 'p01'
    outputs = 'console'
  []
  [m01_expect]
    type = ParsedPostprocessor
    expression = 'm01_prev - del_m01'
    pp_names = 'm01_prev del_m01'
  []
  [p11]
    type = PointValue
    point = '1 1 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
[]
[BCs]
  [flux]
    type = PorousFlowSink
    boundary = 'left'
    variable = pp
    use_mobility = true
    use_relperm = true
    fluid_phase = 0
    flux_function = 6
    save_in = flux_out
  []
[]
[Preconditioning]
  [andy]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -snes_max_it -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres asm lu 10000 NONZERO 2'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 1E-3
  end_time = 0.03
  nl_rel_tol = 1E-12
  nl_abs_tol = 1E-12
[]
[Outputs]
  file_base = s02
  [console]
    type = Console
    execute_on = 'nonlinear linear'
    time_step_interval = 30
  []
  [csv]
    type = CSV
    execute_on = 'timestep_end'
    time_step_interval = 3
  []
[]
(modules/porous_flow/test/tests/sinks/s08.i)
# apply a sink flux on just one component of a 3-component, 2-phase system and observe the correct behavior
[Mesh]
  type = GeneratedMesh
  dim = 3
  nx = 1
  ny = 1
  nz = 1
  xmin = 0
  xmax = 1
  ymin = 0
  ymax = 1
  zmin = 0
  zmax = 2
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pwater frac_ph0_c0 pgas'
    number_fluid_phases = 2
    number_fluid_components = 3
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    m = 0.5
    alpha = 1.1
  []
[]
[Variables]
  [pwater]
  []
  [frac_ph0_c0]
    initial_condition = 0.3
  []
  [pgas]
  []
[]
[ICs]
  [pwater]
    type = FunctionIC
    variable = pwater
    function = y
  []
  [pgas]
    type = FunctionIC
    variable = pgas
    function = y+3
  []
[]
[Kernels]
  [mass_c0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = frac_ph0_c0
  []
  [mass_c1]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = pwater
  []
  [mass_c2]
    type = PorousFlowMassTimeDerivative
    fluid_component = 2
    variable = pgas
  []
[]
[FluidProperties]
  [simple_fluid0]
    type = SimpleFluidProperties
    bulk_modulus = 2.3
    density0 = 1.5
    thermal_expansion = 0
    viscosity = 2.1
  []
  [simple_fluid1]
    type = SimpleFluidProperties
    bulk_modulus = 1.3
    density0 = 1.1
    thermal_expansion = 0
    viscosity = 1.1
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow2PhasePP
    phase0_porepressure = pwater
    phase1_porepressure = pgas
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'frac_ph0_c0 frac_ph0_c1 frac_ph1_c0 frac_ph1_c1'
  []
  [simple_fluid0]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid0
    phase = 0
  []
  [simple_fluid1]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid1
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '0.2 0 0 0 0.1 0 0 0 0.1'
  []
  [relperm0]
    type = PorousFlowRelativePermeabilityCorey
    n = 1
    phase = 0
  []
  [relperm1]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 1
  []
[]
[AuxVariables]
  [flux_out]
  []
  [frac_ph0_c1]
    initial_condition = 0.35
  []
  [frac_ph1_c0]
    initial_condition = 0.1
  []
  [frac_ph1_c1]
    initial_condition = 0.8
  []
[]
[Postprocessors]
  [total_mass_comp0]
    type = PorousFlowFluidMass
    fluid_component = 0
  []
  [total_mass_comp1]
    type = PorousFlowFluidMass
    fluid_component = 1
  []
  [total_mass_comp2]
    type = PorousFlowFluidMass
    fluid_component = 2
  []
  [frac_ph1_c1_00]
    type = PointValue
    point = '0 0 0'
    variable = frac_ph1_c1
    execute_on = 'initial timestep_end'
  []
  [frac_ph0_c1_00]
    type = PointValue
    point = '0 0 0'
    variable = frac_ph0_c1
    execute_on = 'initial timestep_end'
  []
  [flux_00]
    type = PointValue
    point = '0 0 0'
    variable = flux_out
    execute_on = 'initial timestep_end'
  []
  [pgas_00]
    type = PointValue
    point = '0 0 0'
    variable = pgas
    execute_on = 'initial timestep_end'
  []
  [pwater_00]
    type = PointValue
    point = '0 0 0'
    variable = pwater
    execute_on = 'initial timestep_end'
  []
  [m1_00]
    type = ParsedPostprocessor
    expression = 'frac_ph1_c1_00*vol*por*dens0gas*exp(pgas_00/bulkgas)*(1-pow(1+pow(al*(pgas_00-pwater_00),1.0/(1-m)),-m))+frac_ph0_c1_00*vol*por*dens0water*exp(pwater_00/bulkwater)*(pow(1+pow(al*(pgas_00-pwater_00),1.0/(1-m)),-m))'
    constant_names = 'vol  por dens0gas bulkgas al m dens0water bulkwater'
    constant_expressions = '0.25 0.1 1.1 1.3 1.1 0.5 1.5 2.3'
    pp_names = 'pgas_00 pwater_00 frac_ph1_c1_00 frac_ph0_c1_00'
    execute_on = 'initial timestep_end'
  []
  [dm1_00]
    type = ChangeOverTimePostprocessor
    postprocessor = m1_00
    outputs = none
  []
  [m1_00_prev]
    type = ParsedPostprocessor
    expression = 'm1_00 - dm1_00'
    pp_names = 'm1_00 dm1_00'
    outputs = 'console'
  []
  [del_m1_00]
    type = ParsedPostprocessor
    expression = 'frac_ph1_c1_00*fcn*area*dt*pow(1-pow(1+pow(al*(pgas_00-pwater_00),1.0/(1-m)),-m), 2)'
    constant_names = 'fcn area dt al m'
    constant_expressions = '100 0.5 1E-3 1.1 0.5'
    pp_names = 'frac_ph1_c1_00 pgas_00 pwater_00'
    outputs = 'console'
  []
  [m1_00_expect]
    type = ParsedPostprocessor
    expression = 'm1_00_prev - del_m1_00'
    pp_names = 'm1_00_prev del_m1_00'
  []
[]
[BCs]
  [flux_ph1_c1]
    type = PorousFlowSink
    boundary = 'left'
    variable = pwater # sink applied to the mass_c1 Kernel
    use_mobility = false
    use_relperm = true
    mass_fraction_component = 1
    fluid_phase = 1
    flux_function = 100
    save_in = flux_out
  []
[]
[Preconditioning]
  [andy]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -snes_max_it -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres asm lu 100 NONZERO 2'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 1E-3
  end_time = 0.01
  nl_rel_tol = 1E-12
  nl_abs_tol = 1E-12
[]
[Outputs]
  file_base = s08
  exodus = true
  [console]
    type = Console
    execute_on = 'nonlinear linear'
  []
  [csv]
    type = CSV
    execute_on = 'timestep_end'
  []
[]
(modules/porous_flow/test/tests/sinks/s11.i)
# Test PorousFlowEnthalpySink boundary condition
[Mesh]
  type = GeneratedMesh
  dim = 3
  nx = 2
  ny = 2
  nz = 2
  xmin = 0
  xmax = 10
  ymin = 0
  ymax = 10
  zmin = 0
  zmax = 10
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp temp'
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureConst
    pc = 0.1
  []
[]
[Variables]
  [pp]
    initial_condition = 1
  []
  [temp]
    initial_condition = 2
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pp
  []
  [heat_conduction]
    type = TimeDerivative
    variable = temp
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 1
    density0 = 10
    thermal_expansion = 0
    viscosity = 11
  []
[]
[Materials]
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pp
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.125
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
[]
[BCs]
  [left_p]
    type = PorousFlowSink
    variable = pp
    boundary = left
    flux_function = -1
  []
  [left_T]
    # Note, there is no `fluid_phase` or `porepressure_var` prescribed, since they are passed in from the `tests` file
    type = PorousFlowEnthalpySink
    variable = temp
    boundary = left
    T_in = 300
    fp = simple_fluid
    flux_function = -1
  []
[]
[Preconditioning]
  [andy]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.25
  end_time = 1
  nl_rel_tol = 1E-12
  nl_abs_tol = 1E-12
[]
[Outputs]
  file_base = s11
  [exodus]
    type = Exodus
    execute_on = 'initial final'
  []
[]
(modules/porous_flow/test/tests/fluidstate/theis_nonisothermal.i)
# Two-phase nonisothermal Theis problem: Flow from single source using WaterNCG fluidstate.
# Constant rate injection 2 kg/s of cold gas into warm reservoir
# 1D cylindrical mesh
# Initially, system has only a liquid phase, until enough gas is injected
# to form a gas phase, in which case the system becomes two phase.
[Mesh]
  [mesh]
    type = GeneratedMeshGenerator
    dim = 1
    nx = 40
    xmin = 0.1
    xmax = 200
    bias_x = 1.05
  []
  coord_type = RZ
  rz_coord_axis = Y
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[AuxVariables]
  [saturation_gas]
    order = CONSTANT
    family = MONOMIAL
  []
  [x1]
    order = CONSTANT
    family = MONOMIAL
  []
  [y0]
    order = CONSTANT
    family = MONOMIAL
  []
[]
[AuxKernels]
  [saturation_gas]
    type = PorousFlowPropertyAux
    variable = saturation_gas
    property = saturation
    phase = 1
    execute_on = timestep_end
  []
  [x1]
    type = PorousFlowPropertyAux
    variable = x1
    property = mass_fraction
    phase = 0
    fluid_component = 1
    execute_on = timestep_end
  []
  [y0]
    type = PorousFlowPropertyAux
    variable = y0
    property = mass_fraction
    phase = 1
    fluid_component = 0
    execute_on = timestep_end
  []
[]
[Variables]
  [pgas]
    initial_condition = 20e6
  []
  [zi]
    initial_condition = 0
  []
  [temperature]
    initial_condition = 70
    scaling = 1e-4
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pgas
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pgas
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = zi
  []
  [flux1]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    variable = zi
  []
  [energy]
    type = PorousFlowEnergyTimeDerivative
    variable = temperature
  []
  [heatadv]
    type = PorousFlowHeatAdvection
    variable = temperature
  []
  [conduction]
    type = PorousFlowHeatConduction
    variable = temperature
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pgas zi temperature'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureConst
    pc = 0
  []
  [fs]
    type = PorousFlowWaterNCG
    water_fp = water
    gas_fp = methane
    capillary_pressure = pc
  []
[]
[FluidProperties]
  [methane]
    type = MethaneFluidProperties
  []
  [water]
    type = Water97FluidProperties
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = temperature
  []
  [waterncg]
    type = PorousFlowFluidState
    gas_porepressure = pgas
    z = zi
    temperature = temperature
    temperature_unit = Celsius
    capillary_pressure = pc
    fluid_state = fs
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.2
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1e-12 0 0 0 1e-12 0 0 0 1e-12'
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
    s_res = 0.1
    sum_s_res = 0.1
  []
  [relperm_gas]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 1
  []
  [rockheat]
    type = PorousFlowMatrixInternalEnergy
    specific_heat_capacity = 1000
    density = 2500
  []
  [rock_thermal_conductivity]
    type = PorousFlowThermalConductivityIdeal
    dry_thermal_conductivity = '50 0 0  0 50 0  0 0 50'
  []
[]
[BCs]
  [cold_gas]
    type = DirichletBC
    boundary = left
    variable = temperature
    value = 20
  []
  [gas_injecton]
    type = PorousFlowSink
    boundary = left
    variable = zi
    flux_function = -0.159155
  []
  [rightwater]
    type = DirichletBC
    boundary = right
    value = 20e6
    variable = pgas
  []
  [righttemp]
    type = DirichletBC
    boundary = right
    value = 70
    variable = temperature
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres      asm      lu           NONZERO                   2'
  []
[]
[Executioner]
  type = Transient
  solve_type = NEWTON
  end_time = 1e4
  nl_abs_tol = 1e-7
  nl_rel_tol = 1e-5
  # Avoids failing first time step in parallel
  line_search = 'none'
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1
    growth_factor = 1.5
  []
[]
[Postprocessors]
  [pgas]
    type = PointValue
    point = '2 0 0'
    variable = pgas
  []
  [sgas]
    type = PointValue
    point = '2 0 0'
    variable = saturation_gas
  []
  [zi]
    type = PointValue
    point = '2 0 0'
    variable = zi
  []
  [temperature]
    type = PointValue
    point = '2 0 0'
    variable = temperature
  []
  [massgas]
    type = PorousFlowFluidMass
    fluid_component = 1
  []
  [x1]
    type = PointValue
    point = '2 0 0'
    variable = x1
  []
  [y0]
    type = PointValue
    point = '2 0 0'
    variable = y0
  []
[]
[Outputs]
  print_linear_residuals = false
  perf_graph = true
  csv = true
[]
(modules/porous_flow/test/tests/infiltration_and_drainage/rsc02.i)
# RSC test with low-res time and spatial resolution
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 200
  ny = 1
  xmin = 0
  xmax = 10 # x is the depth variable, called zeta in RSC
  ymin = 0
  ymax = 0.05
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[Functions]
  [dts]
    type = PiecewiseLinear
    y = '3E-2 5E-1 8E-1'
    x = '0 1 5'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pwater poil'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureRSC
    oil_viscosity = 2E-3
    scale_ratio = 2E3
    shift = 10
  []
[]
[FluidProperties]
  [water]
    type = SimpleFluidProperties
    bulk_modulus = 2e9
    density0 = 10
    thermal_expansion = 0
    viscosity = 1e-3
  []
  [oil]
    type = SimpleFluidProperties
    bulk_modulus = 2e9
    density0 = 20
    thermal_expansion = 0
    viscosity = 2e-3
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow2PhasePP
    phase0_porepressure = pwater
    phase1_porepressure = poil
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'massfrac_ph0_sp0 massfrac_ph1_sp0'
  []
  [water]
    type = PorousFlowSingleComponentFluid
    fp = water
    phase = 0
    compute_enthalpy = false
    compute_internal_energy = false
  []
  [oil]
    type = PorousFlowSingleComponentFluid
    fp = oil
    phase = 1
    compute_enthalpy = false
    compute_internal_energy = false
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 1
    phase = 0
  []
  [relperm_oil]
    type = PorousFlowRelativePermeabilityCorey
    n = 1
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.25
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1E-5 0 0  0 1E-5 0  0 0 1E-5'
  []
[]
[Variables]
  [pwater]
  []
  [poil]
  []
[]
[ICs]
  [water_init]
    type = ConstantIC
    variable = pwater
    value = 0
  []
  [oil_init]
    type = ConstantIC
    variable = poil
    value = 15
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pwater
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pwater
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = poil
  []
  [flux1]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    variable = poil
  []
[]
[AuxVariables]
  [SWater]
    family = MONOMIAL
    order = CONSTANT
  []
  [SOil]
    family = MONOMIAL
    order = CONSTANT
  []
  [massfrac_ph0_sp0]
    initial_condition = 1
  []
  [massfrac_ph1_sp0]
    initial_condition = 0
  []
[]
[AuxKernels]
  [SWater]
    type = MaterialStdVectorAux
    property = PorousFlow_saturation_qp
    index = 0
    variable = SWater
  []
  [SOil]
    type = MaterialStdVectorAux
    property = PorousFlow_saturation_qp
    index = 1
    variable = SOil
  []
[]
[BCs]
# we are pumping water into a system that has virtually incompressible fluids, hence the pressures rise enormously.  this adversely affects convergence because of almost-overflows and precision-loss problems.  The fixed things help keep pressures low and so prevent these awful behaviours.   the movement of the saturation front is the same regardless of the fixed things.
  active = 'recharge fixedoil fixedwater'
  [recharge]
    type = PorousFlowSink
    variable = pwater
    boundary = 'left'
    flux_function = -1.0
  []
  [fixedwater]
    type = DirichletBC
    variable = pwater
    boundary = 'right'
    value = 0
  []
  [fixedoil]
    type = DirichletBC
    variable = poil
    boundary = 'right'
    value = 15
  []
[]
[Preconditioning]
  [andy]
    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               1E-10      1E-10      10000'
  []
[]
[VectorPostprocessors]
  [swater]
    type = LineValueSampler
    warn_discontinuous_face_values = false
    variable = SWater
    start_point = '0 0 0'
    end_point = '7 0 0'
    sort_by = x
    num_points = 21
    execute_on = timestep_end
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  petsc_options = '-snes_converged_reason'
  end_time = 5
  [TimeStepper]
    type = FunctionDT
    function = dts
  []
[]
[Outputs]
  file_base = rsc02
  [along_line]
    type = CSV
    execute_vector_postprocessors_on = final
  []
  [exodus]
    type = Exodus
    execute_on = 'initial final'
  []
[]
(modules/porous_flow/test/tests/sinks/injection_production_eg_outflowBC.i)
# phase = 0 is liquid phase
# phase = 1 is gas phase
# fluid_component = 0 is water
# fluid_component = 1 is CO2
# Constant rates of water and CO2 injection into the left boundary
# 1D mesh
# The PorousFlowOutflowBCs remove the correct water and CO2 from the right boundary
[Mesh]
  type = GeneratedMesh
  dim = 1
  nx = 20
  xmax = 20
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[AuxVariables]
  [saturation_gas]
    order = CONSTANT
    family = MONOMIAL
  []
  [frac_water_in_liquid]
    initial_condition = 1.0
  []
  [frac_water_in_gas]
    initial_condition = 0.0
  []
  [water_kg_per_s]
  []
  [co2_kg_per_s]
  []
[]
[AuxKernels]
  [saturation_gas]
    type = PorousFlowPropertyAux
    variable = saturation_gas
    property = saturation
    phase = 1
    execute_on = timestep_end
  []
[]
[Variables]
  [pwater]
    initial_condition = 20E6
  []
  [pgas]
    initial_condition = 21E6
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pwater
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pwater
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = pgas
  []
  [flux1]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    variable = pgas
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pgas pwater'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    alpha = 1E-6
    m = 0.6
  []
[]
[FluidProperties]
  [true_water]
    type = Water97FluidProperties
  []
  [tabulated_water]
    type = TabulatedBicubicFluidProperties
    fp = true_water
    temperature_min = 275
    pressure_max = 1E8
    interpolated_properties = 'density viscosity enthalpy internal_energy'
    fluid_property_output_file = water97_tabulated_11.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = water97_tabulated_11.csv
  []
  [true_co2]
    type = CO2FluidProperties
  []
  [tabulated_co2]
    type = TabulatedBicubicFluidProperties
    fp = true_co2
    temperature_min = 275
    pressure_max = 1E8
    interpolated_properties = 'density viscosity enthalpy internal_energy'
    fluid_property_output_file = co2_tabulated_11.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = co2_tabulated_11.csv
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 293.15
  []
  [saturation_calculator]
    type = PorousFlow2PhasePP
    phase0_porepressure = pwater
    phase1_porepressure = pgas
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'frac_water_in_liquid frac_water_in_gas'
  []
  [water]
    type = PorousFlowSingleComponentFluid
    fp = tabulated_water
    phase = 0
  []
  [co2]
    type = PorousFlowSingleComponentFluid
    fp = tabulated_co2
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.2
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1e-12 0 0 0 1e-12 0 0 0 1e-12'
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
    s_res = 0.1
    sum_s_res = 0.2
  []
  [relperm_gas]
    type = PorousFlowRelativePermeabilityBC
    nw_phase = true
    lambda = 2
    s_res = 0.1
    sum_s_res = 0.2
    phase = 1
  []
[]
[BCs]
  [water_injection]
    type = PorousFlowSink
    boundary = left
    variable = pwater # pwater is associated with the water mass balance (fluid_component = 0 in its Kernels)
    flux_function = -1E-5 # negative means a source, rather than a sink
  []
  [co2_injection]
    type = PorousFlowSink
    boundary = left
    variable = pgas # pgas is associated with the CO2 mass balance (fluid_component = 1 in its Kernels)
    flux_function = -2E-5 # negative means a source, rather than a sink
  []
  [right_water_component0]
    type = PorousFlowOutflowBC
    boundary = right
    variable = pwater
    mass_fraction_component = 0
    save_in = water_kg_per_s
  []
  [right_co2_component1]
    type = PorousFlowOutflowBC
    boundary = right
    variable = pgas
    mass_fraction_component = 1
    save_in = co2_kg_per_s
  []
[]
[Preconditioning]
  active = 'basic'
  [basic]
    type = SMP
    full = true
    petsc_options = '-snes_converged_reason -ksp_diagonal_scale -ksp_diagonal_scale_fix -ksp_gmres_modifiedgramschmidt'
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres asm lu NONZERO 2'
  []
  [preferred]
    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
  nl_abs_tol = 1E-10
  nl_rel_tol = 1E-10
  end_time = 1E5
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1E5
    growth_factor = 1.1
  []
[]
[Postprocessors]
  [water_kg_per_s]
    type = NodalSum
    boundary = right
    variable = water_kg_per_s
  []
  [co2_kg_per_s]
    type = NodalSum
    boundary = right
    variable = co2_kg_per_s
  []
[]
[VectorPostprocessors]
  [pps]
    type = LineValueSampler
    start_point = '0 0 0'
    end_point = '20 0 0'
    num_points = 20
    sort_by = x
    variable = 'pgas pwater saturation_gas'
  []
[]
[Outputs]
  [out]
    type = CSV
    execute_on = final
  []
[]
(modules/porous_flow/test/tests/infiltration_and_drainage/rd01.i)
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 120
  ny = 1
  xmin = 0
  xmax = 6
  ymin = 0
  ymax = 0.05
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Functions]
  [dts]
    type = PiecewiseLinear
    y = '1E-2 1 10 500 5000 5000'
    x = '0 10 100 1000 10000 100000'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = pressure
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    m = 0.336
    alpha = 1.43e-4
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e7
    viscosity = 1.01e-3
    density0 = 1000
    thermal_expansion = 0
  []
[]
[Materials]
  [massfrac]
    type = PorousFlowMassFraction
  []
  [temperature]
    type = PorousFlowTemperature
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = pressure
    capillary_pressure = pc
  []
  [relperm]
    type = PorousFlowRelativePermeabilityVG
    m = 0.336
    seff_turnover = 0.99
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.33
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '0.295E-12 0 0  0 0.295E-12 0  0 0 0.295E-12'
  []
[]
[Variables]
  [pressure]
    initial_condition = -72620.4
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pressure
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pressure
    gravity = '-10 0 0'
  []
[]
[AuxVariables]
  [SWater]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [SWater]
    type = MaterialStdVectorAux
    property = PorousFlow_saturation_qp
    index = 0
    variable = SWater
  []
[]
[BCs]
  [base]
    type = PorousFlowSink
    boundary = right
    flux_function = -2.315E-3
    variable = pressure
  []
[]
[Preconditioning]
  [andy]
    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               1E-10      1E-10      10'
  []
[]
[VectorPostprocessors]
  [swater]
    type = LineValueSampler
    warn_discontinuous_face_values = false
    variable = SWater
    start_point = '0 0 0'
    end_point = '6 0 0'
    sort_by = x
    num_points = 121
    execute_on = timestep_end
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  petsc_options = '-snes_converged_reason'
  end_time = 359424
  [TimeStepper]
    type = FunctionDT
    function = dts
  []
[]
[Outputs]
  file_base = rd01
  [exodus]
    type = Exodus
    execute_on = 'initial final'
  []
  [along_line]
    type = CSV
    execute_on = final
  []
[]
(modules/porous_flow/examples/groundwater/ex02_abstraction.i)
# Abstraction groundwater model.  See groundwater_models.md for a detailed description
[Mesh]
  [from_steady_state]
    type = FileMeshGenerator
    file = gold/ex02_steady_state_ex.e
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Variables]
  [pp]
  []
[]
[ICs]
  [pp]
    type = FunctionIC
    variable = pp
    function = steady_state_pp
  []
[]
[BCs]
  [rainfall_recharge]
    type = PorousFlowSink
    boundary = zmax
    variable = pp
    flux_function = -1E-6  # recharge of 0.1mm/day = 1E-4m3/m2/day = 0.1kg/m2/day ~ 1E-6kg/m2/s
  []
  [evapotranspiration]
    type = PorousFlowHalfCubicSink
    boundary = zmax
    variable = pp
    center = 0.0
    cutoff = -5E4 # roots of depth 5m.  5m of water = 5E4 Pa
    use_mobility = true
    fluid_phase = 0
    # Assume pan evaporation of 4mm/day = 4E-3m3/m2/day = 4kg/m2/day ~ 4E-5kg/m2/s
    # Assume that if permeability was 1E-10m^2 and water table at topography then ET acts as pan strength
    # Because use_mobility = true, then 4E-5 = maximum_flux = max * perm * density / visc = max * 1E-4, so max = 40
    max = 40
  []
[]
[DiracKernels]
  inactive = polyline_sink_borehole
  [river]
    type = PorousFlowPolyLineSink
    SumQuantityUO = baseflow
    point_file = ex02_river.bh
    # Assume a perennial river.
    # Assume the river has an incision depth of 1m and a stage height of 1.5m, and these are constant in time and uniform over the whole model.  Hence, if groundwater head is 0.5m (5000Pa) there will be no baseflow and leakage.
    p_or_t_vals = '-999995000 5000 1000005000'
    # Assume the riverbed conductance, k_zz*density*river_segment_length*river_width/riverbed_thickness/viscosity = 1E-6*river_segment_length kg/Pa/s
    fluxes = '-1E3 0 1E3'
    variable = pp
  []
  [horizontal_borehole]
    type = PorousFlowPeacemanBorehole
    SumQuantityUO = abstraction
    bottom_p_or_t = -1E5
    unit_weight = '0 0 -1E4'
    character = 1.0
    point_file = ex02.bh
    variable = pp
  []
  [polyline_sink_borehole]
    type = PorousFlowPolyLineSink
    SumQuantityUO = abstraction
    fluxes = '-0.4 0 0.4'
    p_or_t_vals = '-1E8 0 1E8'
    point_file = ex02.bh
    variable = pp
  []
[]
[Functions]
  [steady_state_pp]
    type = SolutionFunction
    from_variable = pp
    solution = steady_state_solution
  []
  [baseflow_rate]
    type = ParsedFunction
    symbol_names = 'baseflow_kg dt'
    symbol_values = 'baseflow_kg dt'
    expression = 'baseflow_kg / dt * 24.0 * 3600.0 / 400.0'
  []
  [abstraction_rate]
    type = ParsedFunction
    symbol_names = 'abstraction_kg dt'
    symbol_values = 'abstraction_kg dt'
    expression = 'abstraction_kg / dt * 24.0 * 3600.0'
  []
[]
[AuxVariables]
  [ini_pp]
  []
  [pp_change]
  []
[]
[AuxKernels]
  [ini_pp]
    type = FunctionAux
    variable = ini_pp
    function = steady_state_pp
    execute_on = INITIAL
  []
  [pp_change]
    type = ParsedAux
    variable = pp_change
    coupled_variables = 'pp ini_pp'
    expression = 'pp - ini_pp'
  []
[]
[PorousFlowUnsaturated]
  fp = simple_fluid
  porepressure = pp
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[Materials]
  [porosity_everywhere]
    type = PorousFlowPorosityConst
    porosity = 0.05
  []
  [permeability_aquifers]
    type = PorousFlowPermeabilityConst
    block = 'top_aquifer bot_aquifer'
    permeability = '1E-12 0 0 0 1E-12 0 0 0 1E-13'
  []
  [permeability_aquitard]
    type = PorousFlowPermeabilityConst
    block = aquitard
    permeability = '1E-16 0 0 0 1E-16 0 0 0 1E-17'
  []
[]
[UserObjects]
  [steady_state_solution]
    type = SolutionUserObject
    execute_on = INITIAL
    mesh = gold/ex02_steady_state_ex.e
    timestep = LATEST
    system_variables = pp
  []
  [baseflow]
    type = PorousFlowSumQuantity
  []
  [abstraction]
    type = PorousFlowSumQuantity
  []
[]
[Postprocessors]
  [baseflow_kg]
    type = PorousFlowPlotQuantity
    uo = baseflow
    outputs = 'none'
  []
  [dt]
    type = TimestepSize
    outputs = 'none'
  []
  [baseflow_l_per_m_per_day]
    type = FunctionValuePostprocessor
    function = baseflow_rate
    indirect_dependencies = 'baseflow_kg dt'
  []
  [abstraction_kg]
    type = PorousFlowPlotQuantity
    uo = abstraction
    outputs = 'none'
  []
  [abstraction_kg_per_day]
    type = FunctionValuePostprocessor
    function = abstraction_rate
    indirect_dependencies = 'abstraction_kg dt'
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
    # following 2 lines are not mandatory, but illustrate a popular preconditioner choice in groundwater models
    petsc_options_iname = '-pc_type -sub_pc_type  -pc_asm_overlap'
    petsc_options_value = ' asm      ilu           2              '
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 100
  [TimeStepper]
    type = FunctionDT
    function = 'max(100, t)'
  []
  end_time = 8.64E5 # 10 days
  nl_abs_tol = 1E-11
[]
[Outputs]
  print_linear_residuals = false
  [ex]
    type = Exodus
    execute_on = final
  []
  [csv]
    type = CSV
  []
[]
(modules/porous_flow/examples/tutorial/08_KT.i)
# Unsaturated Darcy-Richards flow
[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]
  []
[]
[PorousFlowUnsaturated]
  porepressure = porepressure
  coupling_type = Hydro
  gravity = '0 0 0'
  fp = the_simple_fluid
  relative_permeability_exponent = 3
  relative_permeability_type = Corey
  residual_saturation = 0.1
  van_genuchten_alpha = 1E-6
  van_genuchten_m = 0.6
  stabilization = KT
  flux_limiter_type = None
[]
[BCs]
  [production]
    type = PorousFlowSink
    variable = porepressure
    fluid_phase = 0
    flux_function = 1E-2
    use_relperm = true
    boundary = injection_area
  []
[]
[FluidProperties]
  [the_simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2E9
    viscosity = 1.0E-3
    density0 = 1000.0
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosity
    porosity_zero = 0.1
  []
  [permeability_aquifer]
    type = PorousFlowPermeabilityConst
    block = aquifer
    permeability = '1E-14 0 0   0 1E-14 0   0 0 1E-14'
  []
  [permeability_caps]
    type = PorousFlowPermeabilityConst
    block = caps
    permeability = '1E-15 0 0   0 1E-15 0   0 0 1E-16'
  []
[]
[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 = 1E5
  dt = 1E5
  nl_rel_tol = 1E-14
[]
[Outputs]
  exodus = true
[]
(modules/porous_flow/examples/restart/gas_injection_new_mesh.i)
# Using the results from the equilibrium run to provide the initial condition for
# porepressure, we now inject a gas phase into the brine-saturated reservoir. In this
# example, the mesh is not identical to the mesh used in gravityeq.i. Rather, it is
# generated so that it is more refined near the injection boundary and at the top of
# the model, as that is where the gas plume will be present.
#
# To use the hydrostatic pressure calculated using the gravity equilibrium run as the initial
# condition for the pressure, a SolutionUserObject is used, along with a SolutionFunction to
# interpolate the pressure from the gravity equilibrium run to the initial condition for liqiud
# porepressure in this example.
#
# Even though the gravity equilibrium is established using a 2D mesh, in this example,
# we use a mesh shifted 0.1 m to the right and rotate it about the Y axis to make a 2D radial
# model.
#
# Methane injection takes place over the surface of the hole created by rotating the mesh,
# and hence the injection area is 2 pi r h. We can calculate this using an AreaPostprocessor,
# and then use this in a ParsedFunction to calculate the injection rate so that 10 kg/s of
# methane is injected.
#
# Note: as this example uses the results from a previous simulation, gravityeq.i MUST be
# run before running this input file.
[Mesh]
  type = GeneratedMesh
  dim = 2
  ny = 25
  nx = 50
  ymax = 100
  xmin = 0.1
  xmax = 5000
  bias_x = 1.05
  bias_y = 0.95
  coord_type = RZ
  rz_coord_axis = Y
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 -9.81 0'
  temperature_unit = Celsius
[]
[Variables]
  [pp_liq]
  []
  [sat_gas]
    initial_condition = 0
  []
[]
[ICs]
  [ppliq_ic]
    type = FunctionIC
    variable = pp_liq
    function = ppliq_ic
  []
[]
[AuxVariables]
  [temperature]
    initial_condition = 50
  []
  [xnacl]
    initial_condition = 0.1
  []
  [brine_density]
    family = MONOMIAL
    order = CONSTANT
  []
  [methane_density]
    family = MONOMIAL
    order = CONSTANT
  []
  [massfrac_ph0_sp0]
    initial_condition = 1
  []
  [massfrac_ph1_sp0]
    initial_condition = 0
  []
  [pp_gas]
    family = MONOMIAL
    order = CONSTANT
  []
  [sat_liq]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    variable = pp_liq
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    variable = pp_liq
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    variable = sat_gas
    fluid_component = 1
  []
  [flux1]
    type = PorousFlowAdvectiveFlux
    variable = sat_gas
    fluid_component = 1
  []
[]
[AuxKernels]
  [brine_density]
    type = PorousFlowPropertyAux
    property = density
    variable = brine_density
    execute_on = 'initial timestep_end'
  []
  [methane_density]
    type = PorousFlowPropertyAux
    property = density
    variable = methane_density
    phase = 1
    execute_on = 'initial timestep_end'
  []
  [pp_gas]
    type = PorousFlowPropertyAux
    property = pressure
    phase = 1
    variable = pp_gas
    execute_on = 'initial timestep_end'
  []
  [sat_liq]
    type = PorousFlowPropertyAux
    property = saturation
    variable = sat_liq
    execute_on = 'initial timestep_end'
  []
[]
[BCs]
  [gas_injection]
    type = PorousFlowSink
    boundary = left
    variable = sat_gas
    flux_function = injection_rate
    fluid_phase = 1
  []
  [brine_out]
    type = PorousFlowPiecewiseLinearSink
    boundary = right
    variable = pp_liq
    multipliers = '0 1e9'
    pt_vals = '0 1e9'
    fluid_phase = 0
    flux_function = 1e-6
    use_mobility = true
    use_relperm = true
    mass_fraction_component = 0
  []
[]
[Functions]
  [injection_rate]
    type = ParsedFunction
    symbol_values = injection_area
    symbol_names = area
    expression = '-1/area'
  []
  [ppliq_ic]
    type = SolutionFunction
    solution = soln
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp_liq sat_gas'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    alpha = 1e-5
    m = 0.5
    sat_lr = 0.2
    pc_max = 1e7
  []
  [soln]
    type = SolutionUserObject
    mesh = gravityeq_out.e
    system_variables = porepressure
  []
[]
[FluidProperties]
  [brine]
    type = BrineFluidProperties
  []
  [methane]
    type = MethaneFluidProperties
  []
  [methane_tab]
    type = TabulatedBicubicFluidProperties
    fp = methane
    save_file = false
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = temperature
  []
  [ps]
    type = PorousFlow2PhasePS
    phase0_porepressure = pp_liq
    phase1_saturation = sat_gas
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'massfrac_ph0_sp0 massfrac_ph1_sp0'
  []
  [brine]
    type = PorousFlowBrine
    compute_enthalpy = false
    compute_internal_energy = false
    xnacl = xnacl
    phase = 0
  []
  [methane]
    type = PorousFlowSingleComponentFluid
    compute_enthalpy = false
    compute_internal_energy = false
    fp = methane_tab
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1e-13 0 0 0 5e-14 0  0 0 1e-13'
  []
  [relperm_liq]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
    s_res = 0.2
    sum_s_res = 0.3
  []
  [relperm_gas]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 1
    s_res = 0.1
    sum_s_res = 0.3
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
    petsc_options_iname = '-pc_type -sub_pc_type -sub_pc_factor_shift_type'
    petsc_options_value = ' asm      lu           NONZERO'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1e8
  nl_abs_tol = 1e-12
  nl_rel_tol = 1e-06
  nl_max_its = 20
  dtmax = 1e6
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1e1
    growth_factor = 1.5
  []
[]
[Postprocessors]
  [mass_ph0]
    type = PorousFlowFluidMass
    fluid_component = 0
    execute_on = 'initial timestep_end'
  []
  [mass_ph1]
    type = PorousFlowFluidMass
    fluid_component = 1
    execute_on = 'initial timestep_end'
  []
  [injection_area]
    type = AreaPostprocessor
    boundary = left
    execute_on = initial
  []
[]
[Outputs]
  execute_on = 'initial timestep_end'
  exodus = true
  perf_graph = true
[]
(modules/porous_flow/test/tests/sinks/s10.i)
# apply a basic sink fluxes to all boundaries.
# Sink strength = S kg.m^-2.s^-1
#
# Use fully-saturated physics, with no flow
# (permeability is zero).
# Each finite element is (2m)^3 in size, and
# porosity is 0.125, so each element holds 1 m^3
# of fluid.
# With density = 10 exp(pp)
# then each element holds 10 exp(pp) kg of fluid
#
# Each boundary node that is away from other boundaries
# (ie, not on a mesh corner or edge) therefore holds
# 5 exp(pp)
# kg of fluid, which is just density * porosity * volume_of_node
#
# Each of such nodes are exposed to a sink flux of strength
# S * A
# where A is the area controlled by the node (in this case 4 m^2)
#
# So d(5 exp(pp))/dt = -4S, ie
# exp(pp) = exp(pp0) - 0.8 * S * t
#
# This is therefore similar to s01.i .  However, this test is
# run 6 times: one for each boundary.  The purpose of this is
# to ensure that the PorousFlowSink BC removes fluid from the
# correct nodes.  This is nontrivial because of the upwinding
# and storing of Material Properties at nodes.
[Mesh]
  type = GeneratedMesh
  dim = 3
  nx = 5
  ny = 5
  nz = 5
  xmin = 0
  xmax = 10
  ymin = 0
  ymax = 10
  zmin = 0
  zmax = 10
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp'
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    m = 0.5
    alpha = 1
  []
[]
[Variables]
  [pp]
    initial_condition = 1
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pp
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 1
    density0 = 10
    thermal_expansion = 0
    viscosity = 11
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = pp
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.125
  []
[]
[BCs]
  [flux]
    type = PorousFlowSink
    boundary = left
    variable = pp
    use_mobility = false
    use_relperm = false
    fluid_phase = 0
    flux_function = 1
  []
[]
[Preconditioning]
  [andy]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -snes_max_it -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres asm lu 10000 NONZERO 2'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.25
  end_time = 1
  nl_rel_tol = 1E-12
  nl_abs_tol = 1E-12
[]
[Outputs]
  file_base = s10
  [exodus]
    type = Exodus
    execute_on = 'initial final'
  []
[]
(modules/porous_flow/test/tests/sinks/s12.i)
# The PorousFlowEnthalpy sink adds heat energy corresponding to injecting a 1kg/s/m^2 (flux_function = -1)
# of fluid at pressure 0.5 (given by the AuxVariable p_aux) and the input temperature is 300 (given by the T_in parameter).
# SimpleFluidProperties are used, with density0 = 10, bulk_modulus = 1, thermal_expansion = 0, and cv = 1E-4
# density = 10 * exp(0.5 / 1 + 0) = 16.4872
# internal energy = 1E-4 * 300 = 0.03
# enthalpy = 0.03 + 0.5/16.3872 = 0.0603265
# This is applied over an area of 100, so the total energy flux is 6.03265 J/s.
# This the the rate of change of the heat energy reported by the PorousFlowHeatEnergy Postprocessor
[Mesh]
  type = GeneratedMesh
  dim = 3
  nx = 2
  ny = 2
  nz = 2
  xmin = 0
  xmax = 10
  ymin = 0
  ymax = 10
  zmin = 0
  zmax = 10
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp temp'
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureConst
  []
[]
[AuxVariables]
  [p_aux]
    initial_condition = 0.5
  []
[]
[Variables]
  [pp]
    initial_condition = 1
  []
  [temp]
    initial_condition = 2
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pp
  []
  [heat_conduction]
    type = PorousFlowEnergyTimeDerivative
    variable = temp
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 1
    density0 = 10
    thermal_expansion = 0
    cv = 1E-4
  []
[]
[Materials]
  [ppss]
    type = PorousFlow1PhaseFullySaturated
    porepressure = pp
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = temp
  []
  [heat]
    type = PorousFlowMatrixInternalEnergy
    specific_heat_capacity = 2
    density = 3
  []
[]
[BCs]
  [left_p]
    type = PorousFlowSink
    variable = pp
    boundary = left
    flux_function = -1
  []
  [left_T]
    type = PorousFlowEnthalpySink
    variable = temp
    boundary = left
    T_in = 300
    fp = simple_fluid
    flux_function = -1
    porepressure_var = p_aux
  []
[]
[Postprocessors]
  [total_heat_energy]
    type = PorousFlowHeatEnergy
    phase = 0
  []
[]
[Preconditioning]
  [andy]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.25
  num_steps = 2
[]
[Outputs]
  file_base = s12
  [csv]
    type = CSV
  []
[]
(modules/porous_flow/examples/thm_example/2D.i)
# Two phase, temperature-dependent, with mechanics, 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
  []
[]
[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
  []
[]
[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
  []
  [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 = PorousFlowPorosityConst
    porosity = 0.2
  []
  [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
  []
[]
[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
  []
[]
[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'
  []
[]
[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        500'
  []
  [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/sinks/s01.i)
# apply a sink flux and observe the correct behavior
[Mesh]
  type = GeneratedMesh
  dim = 3
  nx = 1
  ny = 1
  nz = 1
  xmin = 0
  xmax = 1
  ymin = 0
  ymax = 1
  zmin = 0
  zmax = 2
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp'
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    m = 0.5
    alpha = 1
  []
[]
[Variables]
  [pp]
  []
[]
[ICs]
  [pp]
    type = FunctionIC
    variable = pp
    function = y+1
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pp
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 1.3
    density0 = 1.1
    thermal_expansion = 0
    viscosity = 1.1
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = pp
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1E-5 0 0 0 1E-5 0 0 0 1E-5'
  []
  [relperm]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
  []
[]
[AuxVariables]
  [flux_out]
  []
  [xval]
  []
  [yval]
  []
[]
[ICs]
  [xval]
    type = FunctionIC
    variable = xval
    function = x
  []
  [yval]
    type = FunctionIC
    variable = yval
    function = y
  []
[]
[Functions]
  [mass00]
    type = ParsedFunction
    expression = 'vol*por*dens0*exp(pp/bulk)'
    symbol_names = 'vol por dens0 pp bulk'
    symbol_values = '0.25 0.1 1.1 p00 1.3'
  []
  [mass01]
    type = ParsedFunction
    expression = 'vol*por*dens0*exp(pp/bulk)'
    symbol_names = 'vol por dens0 pp bulk'
    symbol_values = '0.25 0.1 1.1 p01 1.3'
  []
  [expected_mass_change00]
    type = ParsedFunction
    expression = 'fcn*perm*dens0*exp(pp/bulk)/visc*area*dt'
    symbol_names = 'fcn perm dens0 pp bulk visc area dt'
    symbol_values = '6   1    1      0  1.3  1  0.5  1E-3'
  []
[]
[Postprocessors]
  [p00]
    type = PointValue
    point = '0 0 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [m00]
    type = FunctionValuePostprocessor
    function = mass00
    execute_on = 'initial timestep_end'
  []
  [del_m00]
    type = FunctionValuePostprocessor
    function = expected_mass_change00
    execute_on = 'timestep_end'
  []
  [p10]
    type = PointValue
    point = '1 0 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [p01]
    type = PointValue
    point = '0 1 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [m01]
    type = FunctionValuePostprocessor
    function = mass01
    execute_on = 'initial timestep_end'
  []
  [p11]
    type = PointValue
    point = '1 1 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
[]
[BCs]
  [flux]
    type = PorousFlowSink
    boundary = 'left'
    variable = pp
    use_mobility = false
    use_relperm = true
    fluid_phase = 0
    flux_function = 6
    save_in = flux_out
  []
[]
[Preconditioning]
  [andy]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -snes_max_it -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres asm lu 10000 NONZERO 2'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 1E-3
  end_time = 1E-2
  nl_rel_tol = 1E-12
  nl_abs_tol = 1E-12
[]
[Outputs]
  file_base = s01
  [console]
    type = Console
    execute_on = 'nonlinear linear'
  []
  [csv]
    type = CSV
    execute_on = 'initial timestep_end'
  []
[]
(modules/porous_flow/test/tests/sinks/s03.i)
# apply a sink flux with use_relperm=true and observe the correct behavior
[Mesh]
  type = GeneratedMesh
  dim = 3
  nx = 1
  ny = 1
  nz = 1
  xmin = 0
  xmax = 1
  ymin = 0
  ymax = 1
  zmin = 0
  zmax = 2
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp'
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    m = 0.5
    alpha = 1.1
  []
[]
[Variables]
  [pp]
  []
[]
[ICs]
  [pp]
    type = FunctionIC
    variable = pp
    function = -y
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pp
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 1.3
    density0 = 1.1
    thermal_expansion = 0
    viscosity = 1.1
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = pp
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '0.2 0 0 0 0.1 0 0 0 0.1'
  []
  [relperm]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
  []
[]
[AuxVariables]
  [flux_out]
  []
  [xval]
  []
  [yval]
  []
[]
[ICs]
  [xval]
    type = FunctionIC
    variable = xval
    function = x
  []
  [yval]
    type = FunctionIC
    variable = yval
    function = y
  []
[]
[Functions]
  [mass00]
    type = ParsedFunction
    expression = 'vol*por*dens0*exp(pp/bulk)*pow(1+pow(-al*pp,1.0/(1-m)),-m)'
    symbol_names = 'vol por dens0 pp bulk al m'
    symbol_values = '0.25 0.1 1.1 p00 1.3 1.1 0.5'
  []
  [sat00]
    type = ParsedFunction
    expression = 'pow(1+pow(-al*pp,1.0/(1-m)),-m)'
    symbol_names = 'pp al m'
    symbol_values = 'p00 1.1 0.5'
  []
  [mass01]
    type = ParsedFunction
    expression = 'vol*por*dens0*exp(pp/bulk)*pow(1+pow(-al*pp,1.0/(1-m)),-m)'
    symbol_names = 'vol por dens0 pp bulk al m'
    symbol_values = '0.25 0.1 1.1 p01 1.3 1.1 0.5'
  []
  [expected_mass_change00]
    type = ParsedFunction
    expression = 'fcn*pow(pow(1+pow(-al*pp,1.0/(1-m)),-m),2)*area*dt'
    symbol_names = 'fcn perm dens0 pp bulk visc area dt   al  m'
    symbol_values = '6   0.2  1.1  p00 1.3  1.1  0.5  1E-3 1.1 0.5'
  []
  [expected_mass_change01]
    type = ParsedFunction
    expression = 'fcn*pow(pow(1+pow(-al*pp,1.0/(1-m)),-m),2)*area*dt'
    symbol_names = 'fcn perm dens0 pp bulk visc area dt   al  m'
    symbol_values = '6   0.2  1.1  p01 1.3  1.1  0.5  1E-3 1.1 0.5'
  []
  [mass00_expect]
    type = ParsedFunction
    expression = 'mass_prev-mass_change'
    symbol_names = 'mass_prev mass_change'
    symbol_values = 'm00_prev  del_m00'
  []
  [mass01_expect]
    type = ParsedFunction
    expression = 'mass_prev-mass_change'
    symbol_names = 'mass_prev mass_change'
    symbol_values = 'm01_prev  del_m01'
  []
  [sat01]
    type = ParsedFunction
    expression = 'pow(1+pow(-al*pp,1.0/(1-m)),-m)'
    symbol_names = 'pp al m'
    symbol_values = 'p01 1.1 0.5'
  []
  [expected_mass_change_rate]
    type = ParsedFunction
    expression = 'fcn*pow(pow(1+pow(-al*pp,1.0/(1-m)),-m),2)*area'
    symbol_names = 'fcn perm dens0 pp bulk visc area dt   al  m'
    symbol_values = '6   0.2  1.1  p00 1.3  1.1  0.5  1E-3 1.1 0.5'
  []
[]
[Postprocessors]
  [p00]
    type = PointValue
    point = '0 0 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [m00]
    type = FunctionValuePostprocessor
    function = mass00
    execute_on = 'initial timestep_end'
  []
  [m00_prev]
    type = FunctionValuePostprocessor
    function = mass00
    execute_on = 'timestep_begin'
    outputs = 'console'
  []
  [del_m00]
    type = FunctionValuePostprocessor
    function = expected_mass_change00
    execute_on = 'timestep_end'
    outputs = 'console'
  []
  [m00_expect]
    type = FunctionValuePostprocessor
    function = mass00_expect
    execute_on = 'timestep_end'
  []
  [p10]
    type = PointValue
    point = '1 0 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [p01]
    type = PointValue
    point = '0 1 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [m01]
    type = FunctionValuePostprocessor
    function = mass01
    execute_on = 'initial timestep_end'
  []
  [m01_prev]
    type = FunctionValuePostprocessor
    function = mass01
    execute_on = 'timestep_begin'
    outputs = 'console'
  []
  [del_m01]
    type = FunctionValuePostprocessor
    function = expected_mass_change01
    execute_on = 'timestep_end'
    outputs = 'console'
  []
  [m01_expect]
    type = FunctionValuePostprocessor
    function = mass01_expect
    execute_on = 'timestep_end'
  []
  [p11]
    type = PointValue
    point = '1 1 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [s00]
    type = FunctionValuePostprocessor
    function = sat00
    execute_on = 'initial timestep_end'
  []
  [mass00_rate]
    type = FunctionValuePostprocessor
    function = expected_mass_change_rate
    execute_on = 'initial timestep_end'
  []
[]
[BCs]
  [flux]
    type = PorousFlowSink
    boundary = 'left'
    variable = pp
    use_mobility = false
    use_relperm = true
    fluid_phase = 0
    flux_function = 6
    save_in = flux_out
  []
[]
[Preconditioning]
  [andy]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -snes_max_it -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres asm lu 10 NONZERO 2'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 1E-3
  end_time = 0.018
  nl_rel_tol = 1E-12
  nl_abs_tol = 1E-12
[]
[Outputs]
  file_base = s03
  [console]
    type = Console
    execute_on = 'nonlinear linear'
    time_step_interval = 5
  []
  [csv]
    type = CSV
    execute_on = 'timestep_end'
    time_step_interval = 2
  []
[]
(modules/porous_flow/examples/restart/gas_injection.i)
# Using the results from the equilibrium run to provide the initial condition for
# porepressure, we now inject a gas phase into the brine-saturated reservoir. In this
# example, where the mesh used is identical to the mesh used in gravityeq.i, we can use
# the basic restart capability by simply setting the initial condition for porepressure
# using the results from gravityeq.i.
#
# Even though the gravity equilibrium is established using a 2D mesh, in this example,
# we shift the mesh 0.1 m to the right and rotate it about the Y axis to make a 2D radial
# model.
#
# Methane injection takes place over the surface of the hole created by rotating the mesh,
# and hence the injection area is 2 pi r h. We can calculate this using an AreaPostprocessor,
# and then use this in a ParsedFunction to calculate the injection rate so that 10 kg/s of
# methane is injected.
#
# Results can be improved by uniformly refining the initial mesh.
#
# Note: as this example uses the results from a previous simulation, gravityeq.i MUST be
# run before running this input file.
[Mesh]
  uniform_refine = 1
  [file]
    type = FileMeshGenerator
    file = gravityeq_out.e
  []
  [translate]
    type = TransformGenerator
    transform = TRANSLATE
    vector_value = '0.1 0 0'
    input = file
  []
  coord_type = RZ
  rz_coord_axis = Y
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 -9.81 0'
  temperature_unit = Celsius
[]
[Variables]
  [pp_liq]
    initial_from_file_var = porepressure
  []
  [sat_gas]
    initial_condition = 0
  []
[]
[AuxVariables]
  [temperature]
    initial_condition = 50
  []
  [xnacl]
    initial_condition = 0.1
  []
  [brine_density]
    family = MONOMIAL
    order = CONSTANT
  []
  [methane_density]
    family = MONOMIAL
    order = CONSTANT
  []
  [massfrac_ph0_sp0]
    initial_condition = 1
  []
  [massfrac_ph1_sp0]
    initial_condition = 0
  []
  [pp_gas]
    family = MONOMIAL
    order = CONSTANT
  []
  [sat_liq]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    variable = pp_liq
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    variable = pp_liq
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    variable = sat_gas
    fluid_component = 1
  []
  [flux1]
    type = PorousFlowAdvectiveFlux
    variable = sat_gas
    fluid_component = 1
  []
[]
[AuxKernels]
  [brine_density]
    type = PorousFlowPropertyAux
    property = density
    variable = brine_density
    execute_on = 'initial timestep_end'
  []
  [methane_density]
    type = PorousFlowPropertyAux
    property = density
    variable = methane_density
    phase = 1
    execute_on = 'initial timestep_end'
  []
  [pp_gas]
    type = PorousFlowPropertyAux
    property = pressure
    phase = 1
    variable = pp_gas
    execute_on = 'initial timestep_end'
  []
  [sat_liq]
    type = PorousFlowPropertyAux
    property = saturation
    variable = sat_liq
    execute_on = 'initial timestep_end'
  []
[]
[BCs]
  [gas_injection]
    type = PorousFlowSink
    boundary = left
    variable = sat_gas
    flux_function = injection_rate
    fluid_phase = 1
  []
  [brine_out]
    type = PorousFlowPiecewiseLinearSink
    boundary = right
    variable = pp_liq
    multipliers = '0 1e9'
    pt_vals = '0 1e9'
    fluid_phase = 0
    flux_function = 1e-6
    use_mobility = true
  []
[]
[Functions]
  [injection_rate]
    type = ParsedFunction
    symbol_values = injection_area
    symbol_names = area
    expression = '-10/area'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp_liq sat_gas'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    alpha = 1e-5
    m = 0.5
    sat_lr = 0.2
  []
[]
[FluidProperties]
  [brine]
    type = BrineFluidProperties
  []
  [methane]
    type = MethaneFluidProperties
  []
  [methane_tab]
    type = TabulatedBicubicFluidProperties
    fp = methane
    save_file = false
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = temperature
  []
  [ps]
    type = PorousFlow2PhasePS
    phase0_porepressure = pp_liq
    phase1_saturation = sat_gas
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'massfrac_ph0_sp0 massfrac_ph1_sp0'
  []
  [brine]
    type = PorousFlowBrine
    compute_enthalpy = false
    compute_internal_energy = false
    xnacl = xnacl
    phase = 0
  []
  [methane]
    type = PorousFlowSingleComponentFluid
    compute_enthalpy = false
    compute_internal_energy = false
    fp = methane_tab
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1e-13 0 0 0 1e-13 0  0 0 1e-13'
  []
  [relperm_liq]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
    s_res = 0.2
    sum_s_res = 0.3
  []
  [relperm_gas]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 1
    s_res = 0.1
    sum_s_res = 0.3
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
    petsc_options_iname = '-pc_type -sub_pc_type -sub_pc_factor_shift_type'
    petsc_options_value = ' asm      lu           NONZERO'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  end_time = 1e8
  nl_abs_tol = 1e-12
  nl_rel_tol = 1e-06
  nl_max_its = 20
  dtmax = 1e6
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1e1
  []
[]
[Postprocessors]
  [mass_ph0]
    type = PorousFlowFluidMass
    fluid_component = 0
    execute_on = 'initial timestep_end'
  []
  [mass_ph1]
    type = PorousFlowFluidMass
    fluid_component = 1
    execute_on = 'initial timestep_end'
  []
  [injection_area]
    type = AreaPostprocessor
    boundary = left
    execute_on = initial
  []
[]
[Outputs]
  execute_on = 'initial timestep_end'
  exodus = true
  perf_graph = true
  checkpoint = true
[]
(modules/porous_flow/test/tests/infiltration_and_drainage/rsc01.i)
# RSC test with high-res time and spatial resolution
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 600
  ny = 1
  xmin = 0
  xmax = 10 # x is the depth variable, called zeta in RSC
  ymin = 0
  ymax = 0.05
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[Functions]
  [dts]
    type = PiecewiseLinear
    y = '3E-3 3E-2 0.05'
    x = '0 1 5'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pwater poil'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureRSC
    oil_viscosity = 2E-3
    scale_ratio = 2E3
    shift = 10
  []
[]
[FluidProperties]
  [water]
    type = SimpleFluidProperties
    bulk_modulus = 2e9
    density0 = 10
    thermal_expansion = 0
    viscosity = 1e-3
  []
  [oil]
    type = SimpleFluidProperties
    bulk_modulus = 2e9
    density0 = 20
    thermal_expansion = 0
    viscosity = 2e-3
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow2PhasePP
    phase0_porepressure = pwater
    phase1_porepressure = poil
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'massfrac_ph0_sp0 massfrac_ph1_sp0'
  []
  [water]
    type = PorousFlowSingleComponentFluid
    fp = water
    phase = 0
    compute_enthalpy = false
    compute_internal_energy = false
  []
  [oil]
    type = PorousFlowSingleComponentFluid
    fp = oil
    phase = 1
    compute_enthalpy = false
    compute_internal_energy = false
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 1
    phase = 0
  []
  [relperm_oil]
    type = PorousFlowRelativePermeabilityCorey
    n = 1
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.25
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1E-5 0 0  0 1E-5 0  0 0 1E-5'
  []
[]
[Variables]
  [pwater]
  []
  [poil]
  []
[]
[ICs]
  [water_init]
    type = ConstantIC
    variable = pwater
    value = 0
  []
  [oil_init]
    type = ConstantIC
    variable = poil
    value = 15
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pwater
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pwater
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = poil
  []
  [flux1]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    variable = poil
  []
[]
[AuxVariables]
  [SWater]
    family = MONOMIAL
    order = CONSTANT
  []
  [SOil]
    family = MONOMIAL
    order = CONSTANT
  []
  [massfrac_ph0_sp0]
    initial_condition = 1
  []
  [massfrac_ph1_sp0]
    initial_condition = 0
  []
[]
[AuxKernels]
  [SWater]
    type = MaterialStdVectorAux
    property = PorousFlow_saturation_qp
    index = 0
    variable = SWater
  []
  [SOil]
    type = MaterialStdVectorAux
    property = PorousFlow_saturation_qp
    index = 1
    variable = SOil
  []
[]
[BCs]
# we are pumping water into a system that has virtually incompressible fluids, hence the pressures rise enormously.  this adversely affects convergence because of almost-overflows and precision-loss problems.  The fixed things help keep pressures low and so prevent these awful behaviours.   the movement of the saturation front is the same regardless of the fixed things.
  active = 'recharge fixedoil fixedwater'
  [recharge]
    type = PorousFlowSink
    variable = pwater
    boundary = 'left'
    flux_function = -1.0
  []
  [fixedwater]
    type = DirichletBC
    variable = pwater
    boundary = 'right'
    value = 0
  []
  [fixedoil]
    type = DirichletBC
    variable = poil
    boundary = 'right'
    value = 15
  []
[]
[Preconditioning]
  [andy]
    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               1E-10      1E-10      10000'
  []
[]
[VectorPostprocessors]
  [swater]
    type = LineValueSampler
    warn_discontinuous_face_values = false
    variable = SWater
    start_point = '0 0 0'
    end_point = '7 0 0'
    sort_by = x
    num_points = 21
    execute_on = timestep_end
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  petsc_options = '-snes_converged_reason'
  end_time = 5
  [TimeStepper]
    type = FunctionDT
    function = dts
  []
[]
[Outputs]
  file_base = rsc01
  [along_line]
    type = CSV
    execute_vector_postprocessors_on = final
  []
  [exodus]
    type = Exodus
    execute_on = 'initial final'
  []
[]
(modules/porous_flow/examples/tutorial/11.i)
# Two-phase borehole injection problem
[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'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pwater pgas T disp_x disp_y'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    alpha = 1E-6
    m = 0.6
  []
[]
[GlobalParams]
  displacements = 'disp_x disp_y disp_z'
  gravity = '0 0 0'
  biot_coefficient = 1.0
  PorousFlowDictator = dictator
[]
[Variables]
  [pwater]
    initial_condition = 20E6
  []
  [pgas]
    initial_condition = 20.1E6
  []
  [T]
    initial_condition = 330
    scaling = 1E-5
  []
  [disp_x]
    scaling = 1E-5
  []
  [disp_y]
    scaling = 1E-5
  []
[]
[Kernels]
  [mass_water_dot]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pwater
  []
  [flux_water]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    use_displaced_mesh = false
    variable = pwater
  []
  [vol_strain_rate_water]
    type = PorousFlowMassVolumetricExpansion
    fluid_component = 0
    variable = pwater
  []
  [mass_co2_dot]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = pgas
  []
  [flux_co2]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    use_displaced_mesh = false
    variable = pgas
  []
  [vol_strain_rate_co2]
    type = PorousFlowMassVolumetricExpansion
    fluid_component = 1
    variable = pgas
  []
  [energy_dot]
    type = PorousFlowEnergyTimeDerivative
    variable = T
  []
  [advection]
    type = PorousFlowHeatAdvection
    use_displaced_mesh = false
    variable = T
  []
  [conduction]
    type = PorousFlowHeatConduction
    use_displaced_mesh = false
    variable = T
  []
  [vol_strain_rate_heat]
    type = PorousFlowHeatVolumetricExpansion
    variable = T
  []
  [grad_stress_x]
    type = StressDivergenceTensors
    temperature = T
    variable = disp_x
    eigenstrain_names = thermal_contribution
    use_displaced_mesh = false
    component = 0
  []
  [poro_x]
    type = PorousFlowEffectiveStressCoupling
    variable = disp_x
    use_displaced_mesh = false
    component = 0
  []
  [grad_stress_y]
    type = StressDivergenceTensors
    temperature = T
    variable = disp_y
    eigenstrain_names = thermal_contribution
    use_displaced_mesh = false
    component = 1
  []
  [poro_y]
    type = PorousFlowEffectiveStressCoupling
    variable = disp_y
    use_displaced_mesh = false
    component = 1
  []
[]
[AuxVariables]
  [disp_z]
  []
  [effective_fluid_pressure]
    family = MONOMIAL
    order = CONSTANT
  []
  [mass_frac_phase0_species0]
    initial_condition = 1 # all water in phase=0
  []
  [mass_frac_phase1_species0]
    initial_condition = 0 # no water in phase=1
  []
  [sgas]
    family = MONOMIAL
    order = CONSTANT
  []
  [swater]
    family = MONOMIAL
    order = CONSTANT
  []
  [stress_rr]
    family = MONOMIAL
    order = CONSTANT
  []
  [stress_tt]
    family = MONOMIAL
    order = CONSTANT
  []
  [stress_zz]
    family = MONOMIAL
    order = CONSTANT
  []
  [porosity]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [effective_fluid_pressure]
    type = ParsedAux
    coupled_variables = 'pwater pgas swater sgas'
    expression = 'pwater * swater + pgas * sgas'
    variable = effective_fluid_pressure
  []
  [swater]
    type = PorousFlowPropertyAux
    variable = swater
    property = saturation
    phase = 0
    execute_on = timestep_end
  []
  [sgas]
    type = PorousFlowPropertyAux
    variable = sgas
    property = saturation
    phase = 1
    execute_on = timestep_end
  []
  [stress_rr]
    type = RankTwoScalarAux
    variable = stress_rr
    rank_two_tensor = stress
    scalar_type = RadialStress
    point1 = '0 0 0'
    point2 = '0 0 1'
    execute_on = timestep_end
  []
  [stress_tt]
    type = RankTwoScalarAux
    variable = stress_tt
    rank_two_tensor = stress
    scalar_type = HoopStress
    point1 = '0 0 0'
    point2 = '0 0 1'
    execute_on = timestep_end
  []
  [stress_zz]
    type = RankTwoAux
    variable = stress_zz
    rank_two_tensor = stress
    index_i = 2
    index_j = 2
    execute_on = timestep_end
  []
  [porosity]
    type = PorousFlowPropertyAux
    variable = porosity
    property = porosity
    execute_on = timestep_end
  []
[]
[BCs]
  [roller_tmax]
    type = DirichletBC
    variable = disp_x
    value = 0
    boundary = dmax
  []
  [roller_tmin]
    type = DirichletBC
    variable = disp_y
    value = 0
    boundary = dmin
  []
  [pinned_top_bottom_x]
    type = DirichletBC
    variable = disp_x
    value = 0
    boundary = 'top bottom'
  []
  [pinned_top_bottom_y]
    type = DirichletBC
    variable = disp_y
    value = 0
    boundary = 'top bottom'
  []
  [cavity_pressure_x]
    type = Pressure
    boundary = injection_area
    variable = disp_x
    component = 0
    postprocessor = constrained_effective_fluid_pressure_at_wellbore
    use_displaced_mesh = false
  []
  [cavity_pressure_y]
    type = Pressure
    boundary = injection_area
    variable = disp_y
    component = 1
    postprocessor = constrained_effective_fluid_pressure_at_wellbore
    use_displaced_mesh = false
  []
  [cold_co2]
    type = DirichletBC
    boundary = injection_area
    variable = T
    value = 290 # injection temperature
    use_displaced_mesh = false
  []
  [constant_co2_injection]
    type = PorousFlowSink
    boundary = injection_area
    variable = pgas
    fluid_phase = 1
    flux_function = -1E-4
    use_displaced_mesh = false
  []
  [outer_water_removal]
    type = PorousFlowPiecewiseLinearSink
    boundary = rmax
    variable = pwater
    fluid_phase = 0
    pt_vals = '0 1E9'
    multipliers = '0 1E8'
    PT_shift = 20E6
    use_mobility = true
    use_relperm = true
    use_displaced_mesh = false
  []
  [outer_co2_removal]
    type = PorousFlowPiecewiseLinearSink
    boundary = rmax
    variable = pgas
    fluid_phase = 1
    pt_vals = '0 1E9'
    multipliers = '0 1E8'
    PT_shift = 20.1E6
    use_mobility = true
    use_relperm = true
    use_displaced_mesh = false
  []
[]
[FluidProperties]
  [true_water]
    type = Water97FluidProperties
  []
  [tabulated_water]
    type = TabulatedFluidProperties
    fp = true_water
    temperature_min = 275
    pressure_max = 1E8
    interpolated_properties = 'density viscosity enthalpy internal_energy'
    fluid_property_output_file = water97_tabulated_11.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = water97_tabulated_11.csv
  []
  [true_co2]
    type = CO2FluidProperties
  []
  [tabulated_co2]
    type = TabulatedFluidProperties
    fp = true_co2
    temperature_min = 275
    pressure_max = 1E8
    interpolated_properties = 'density viscosity enthalpy internal_energy'
    fluid_property_output_file = co2_tabulated_11.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = co2_tabulated_11.csv
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = T
  []
  [saturation_calculator]
    type = PorousFlow2PhasePP
    phase0_porepressure = pwater
    phase1_porepressure = pgas
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'mass_frac_phase0_species0 mass_frac_phase1_species0'
  []
  [water]
    type = PorousFlowSingleComponentFluid
    fp = tabulated_water
    phase = 0
  []
  [co2]
    type = PorousFlowSingleComponentFluid
    fp = tabulated_co2
    phase = 1
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 4
    s_res = 0.1
    sum_s_res = 0.2
    phase = 0
  []
  [relperm_co2]
    type = PorousFlowRelativePermeabilityBC
    nw_phase = true
    lambda = 2
    s_res = 0.1
    sum_s_res = 0.2
    phase = 1
  []
  [porosity_mat]
    type = PorousFlowPorosity
    fluid = true
    mechanical = true
    thermal = true
    porosity_zero = 0.1
    reference_temperature = 330
    reference_porepressure = 20E6
    thermal_expansion_coeff = 15E-6 # volumetric
    solid_bulk = 8E9 # unimportant since biot = 1
  []
  [permeability_aquifer]
    type = PorousFlowPermeabilityKozenyCarman
    block = aquifer
    poroperm_function = kozeny_carman_phi0
    phi0 = 0.1
    n = 2
    m = 2
    k0 = 1E-12
  []
  [permeability_caps]
    type = PorousFlowPermeabilityKozenyCarman
    block = caps
    poroperm_function = kozeny_carman_phi0
    phi0 = 0.1
    n = 2
    m = 2
    k0 = 1E-15
    k_anisotropy = '1 0 0  0 1 0  0 0 0.1'
  []
  [rock_thermal_conductivity]
    type = PorousFlowThermalConductivityIdeal
    dry_thermal_conductivity = '2 0 0  0 2 0  0 0 2'
  []
  [rock_internal_energy]
    type = PorousFlowMatrixInternalEnergy
    specific_heat_capacity = 1100
    density = 2300
  []
  [elasticity_tensor]
    type = ComputeIsotropicElasticityTensor
    youngs_modulus = 5E9
    poissons_ratio = 0.0
  []
  [strain]
    type = ComputeSmallStrain
    eigenstrain_names = 'thermal_contribution initial_stress'
  []
  [thermal_contribution]
    type = ComputeThermalExpansionEigenstrain
    temperature = T
    thermal_expansion_coeff = 5E-6 # this is the linear thermal expansion coefficient
    eigenstrain_name = thermal_contribution
    stress_free_temperature = 330
  []
  [initial_strain]
    type = ComputeEigenstrainFromInitialStress
    initial_stress = '20E6 0 0  0 20E6 0  0 0 20E6'
    eigenstrain_name = initial_stress
  []
  [stress]
    type = ComputeLinearElasticStress
  []
  [effective_fluid_pressure_mat]
    type = PorousFlowEffectiveFluidPressure
  []
  [volumetric_strain]
    type = PorousFlowVolumetricStrain
  []
[]
[Postprocessors]
  [effective_fluid_pressure_at_wellbore]
    type = PointValue
    variable = effective_fluid_pressure
    point = '1 0 0'
    execute_on = timestep_begin
    use_displaced_mesh = false
  []
  [constrained_effective_fluid_pressure_at_wellbore]
    type = FunctionValuePostprocessor
    function = constrain_effective_fluid_pressure
    execute_on = timestep_begin
  []
[]
[Functions]
  [constrain_effective_fluid_pressure]
    type = ParsedFunction
    symbol_names = effective_fluid_pressure_at_wellbore
    symbol_values = effective_fluid_pressure_at_wellbore
    expression = 'max(effective_fluid_pressure_at_wellbore, 20E6)'
  []
[]
[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 = 1E3
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1E3
    growth_factor = 1.2
    optimal_iterations = 10
  []
  nl_abs_tol = 1E-7
[]
[Outputs]
  exodus = true
[]
(modules/porous_flow/examples/groundwater/ex02_steady_state.i)
# Steady-state groundwater model.  See groundwater_models.md for a detailed description
[Mesh]
  [basic_mesh]
    # mesh create by external program: lies within -500<=x<=500 and -200<=y<=200, with varying z
    type = FileMeshGenerator
    file = ex02_mesh.e
  []
  [name_blocks]
    type = RenameBlockGenerator
    input = basic_mesh
    old_block = '2 3 4'
    new_block = 'bot_aquifer aquitard top_aquifer'
  []
  [zmax]
    type = SideSetsFromNormalsGenerator
    input = name_blocks
    normal_tol = 0.1
    new_boundary = zmax
    normals = '0 0 1'
  []
  [xmin_bot_aquifer]
    type = ParsedGenerateSideset
    input = zmax
    included_subdomains = 2
    normal = '-1 0 0'
    combinatorial_geometry = 'x <= -500.0'
    new_sideset_name = xmin_bot_aquifer
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Variables]
  [pp]
  []
[]
[ICs]
  [pp]
    type = FunctionIC
    variable = pp
    function = initial_pp
  []
[]
[BCs]
  [rainfall_recharge]
    type = PorousFlowSink
    boundary = zmax
    variable = pp
    flux_function = -1E-6  # recharge of 0.1mm/day = 1E-4m3/m2/day = 0.1kg/m2/day ~ 1E-6kg/m2/s
  []
  [evapotranspiration]
    type = PorousFlowHalfCubicSink
    boundary = zmax
    variable = pp
    center = 0.0
    cutoff = -5E4 # roots of depth 5m.  5m of water = 5E4 Pa
    use_mobility = true
    fluid_phase = 0
    # Assume pan evaporation of 4mm/day = 4E-3m3/m2/day = 4kg/m2/day ~ 4E-5kg/m2/s
    # Assume that if permeability was 1E-10m^2 and water table at topography then ET acts as pan strength
    # Because use_mobility = true, then 4E-5 = maximum_flux = max * perm * density / visc = max * 1E-4, so max = 40
    max = 40
  []
[]
[DiracKernels]
  [river]
    type = PorousFlowPolyLineSink
    SumQuantityUO = baseflow
    point_file = ex02_river.bh
    # Assume a perennial river.
    # Assume the river has an incision depth of 1m and a stage height of 1.5m, and these are constant in time and uniform over the whole model.  Hence, if groundwater head is 0.5m (5000Pa) there will be no baseflow and leakage.
    p_or_t_vals = '-999995000 5000 1000005000'
    # Assume the riverbed conductance, k_zz*density*river_segment_length*river_width/riverbed_thickness/viscosity = 1E-6*river_segment_length kg/Pa/s
    fluxes = '-1E3 0 1E3'
    variable = pp
  []
[]
[Functions]
  [initial_pp]
    type = SolutionFunction
    scale_factor = 1E4
    from_variable = cosflow_depth
    solution = initial_mesh
  []
  [baseflow_rate]
    type = ParsedFunction
    symbol_names = 'baseflow_kg dt'
    symbol_values = 'baseflow_kg dt'
    expression = 'baseflow_kg / dt * 24.0 * 3600.0 / 400.0'
  []
[]
[PorousFlowUnsaturated]
  fp = simple_fluid
  porepressure = pp
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[Materials]
  [porosity_everywhere]
    type = PorousFlowPorosityConst
    porosity = 0.05
  []
  [permeability_aquifers]
    type = PorousFlowPermeabilityConst
    block = 'top_aquifer bot_aquifer'
    permeability = '1E-12 0 0 0 1E-12 0 0 0 1E-13'
  []
  [permeability_aquitard]
    type = PorousFlowPermeabilityConst
    block = aquitard
    permeability = '1E-16 0 0 0 1E-16 0 0 0 1E-17'
  []
[]
[UserObjects]
  [initial_mesh]
    type = SolutionUserObject
    execute_on = INITIAL
    mesh = ex02_mesh.e
    timestep = LATEST
    system_variables = cosflow_depth
  []
  [baseflow]
    type = PorousFlowSumQuantity
  []
[]
[Postprocessors]
  [baseflow_kg]
    type = PorousFlowPlotQuantity
    uo = baseflow
    outputs = 'none'
  []
  [dt]
    type = TimestepSize
    outputs = 'none'
  []
  [baseflow_l_per_m_per_day]
    type = FunctionValuePostprocessor
    function = baseflow_rate
    indirect_dependencies = 'baseflow_kg dt'
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
    # following 2 lines are not mandatory, but illustrate a popular preconditioner choice in groundwater models
    petsc_options_iname = '-pc_type -sub_pc_type  -pc_asm_overlap'
    petsc_options_value = ' asm      ilu           2              '
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 1E6
  [TimeStepper]
    type = FunctionDT
    function = 'max(1E6, t)'
  []
  end_time = 1E12
  nl_abs_tol = 1E-13
[]
[Outputs]
  print_linear_residuals = false
  [ex]
    type = Exodus
    execute_on = final
  []
  [csv]
    type = CSV
  []
[]
(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/infiltration_and_drainage/bw01.i)
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 400
  ny = 1
  xmin = -10
  xmax = 10
  ymin = 0
  ymax = 0.05
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Functions]
  [dts]
    type = PiecewiseLinear
    y = '1E-5 1E-2 1E-2 1E-1'
    x = '0 1E-5 1 10'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = pressure
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureBW
    Sn = 0.0
    Ss = 1.0
    C = 1.5
    las = 2
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e9
    viscosity = 4
    density0 = 10
    thermal_expansion = 0
  []
[]
[Materials]
  [massfrac]
    type = PorousFlowMassFraction
  []
  [temperature]
    type = PorousFlowTemperature
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = pressure
    capillary_pressure = pc
  []
  [relperm]
    type = PorousFlowRelativePermeabilityBW
    Sn = 0.0
    Ss = 1.0
    Kn = 0
    Ks = 1
    C = 1.5
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.25
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1 0 0  0 1 0  0 0 1'
  []
[]
[Variables]
  [pressure]
    initial_condition = -9E2
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pressure
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pressure
    gravity = '-0.1 0 0'
  []
[]
[AuxVariables]
  [SWater]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [SWater]
    type = MaterialStdVectorAux
    property = PorousFlow_saturation_qp
    index = 0
    variable = SWater
  []
[]
[BCs]
  [recharge]
    type = PorousFlowSink
    variable = pressure
    boundary = right
    flux_function = -1.25 # corresponds to Rstar being 0.5 because i have to multiply by density*porosity
  []
[]
[Preconditioning]
  [andy]
    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               1E-10      1E-10      10000'
  []
[]
[VectorPostprocessors]
  [swater]
    type = LineValueSampler
    warn_discontinuous_face_values = false
    variable = SWater
    start_point = '-10 0 0'
    end_point = '10 0 0'
    sort_by = x
    num_points = 101
    execute_on = timestep_end
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  petsc_options = '-snes_converged_reason'
  end_time = 8
  [TimeStepper]
    type = FunctionDT
    function = dts
  []
[]
[Outputs]
  file_base = bw01
  sync_times = '0.5 2 8'
  [exodus]
    type = Exodus
    sync_only = true
  []
  [along_line]
    type = CSV
    sync_only = true
  []
[]
(modules/porous_flow/examples/multiapp_fracture_flow/single_fracture_heat_transfer/fracture_app.i)
# Fracture physics.  Heat is injected at the left end.  Heat advects along the fracture and conducts to the matrix App
[Mesh]
  [generate]
    type = GeneratedMeshGenerator
    dim = 1
    nx = 100
    xmin = 0
    xmax = 100.0
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Variables]
  [frac_P]
    initial_condition = 2 # MPa
  []
  [frac_T]
    initial_condition = 40 # degC
  []
[]
[PorousFlowFullySaturated]
  coupling_type = ThermoHydro
  porepressure = frac_P
  temperature = frac_T
  fp = simple_fluid
  stabilization = KT
  flux_limiter_type = minmod
  gravity = '0 0 0'
  pressure_unit = MPa
  temperature_unit = Celsius
  time_unit = seconds
[]
[Kernels]
  [toMatrix]
    type = PorousFlowHeatMassTransfer
    variable = frac_T
    v = transferred_matrix_T
    transfer_coefficient = 1E2
    save_in = joules_per_s
  []
[]
[Modules]
  [PorousFlow]
    [BCs]
      [left_injection]
        type = PorousFlowSinkBC
        boundary = left
        fluid_phase = 0
        T_in = 373 # Kelvin!
        fp = simple_fluid
        flux_function = -10 # 10 kg/s
      []
    []
  []
[]
[BCs]
  [mass_production]
    type = PorousFlowSink
    boundary = right
    variable = frac_P
    flux_function = 10
  []
  [heat_production]
    type = PorousFlowSink
    boundary = right
    variable = frac_T
    flux_function = 10
    fluid_phase = 0
    use_enthalpy = true
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 1E9 # in Pa
    density0 = 1000
    thermal_expansion = 0 # for simplicity
    viscosity = 1E-3 # in Pa.s
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 1E-2 # includes fracture aperture of 1E-2
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1E-8 0 0   0 1E-8 0   0 0 1E-8' # roughness times a^3/12
  []
  [internal_energy]
    type = PorousFlowMatrixInternalEnergy
    density = 1
    specific_heat_capacity = 0 # basically no rock inside the fracture
  []
  [aq_thermal_conductivity]
    type = PorousFlowThermalConductivityIdeal
    dry_thermal_conductivity = '0.6E-2 0 0  0 0.6E-2 0  0 0 0.6E-2' # thermal conductivity of water times fracture aperture
  []
[]
[AuxVariables]
  [transferred_matrix_T]
  []
  [joules_per_s]
  []
[]
[VectorPostprocessors]
  [heat_transfer_rate]
    type = NodalValueSampler
    outputs = none
    sort_by = id
    variable = joules_per_s
  []
  [frac]
    type = NodalValueSampler
    outputs = frac
    sort_by = x
    variable = 'frac_T frac_P'
  []
[]
[Preconditioning]
  [entire_jacobian]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = NEWTON
  dt = 100
  end_time = 100
[]
[Outputs]
  print_linear_residuals = false
  exodus = true
  [frac]
    type = CSV
    execute_on = final
  []
[]
(modules/porous_flow/test/tests/sinks/s07.i)
# apply a sink flux on just one component of a 3-component system and observe the correct behavior
[Mesh]
  type = GeneratedMesh
  dim = 3
  nx = 1
  ny = 1
  nz = 1
  xmin = 0
  xmax = 1
  ymin = 0
  ymax = 1
  zmin = 0
  zmax = 2
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pp frac0 frac1'
    number_fluid_phases = 1
    number_fluid_components = 3
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    m = 0.5
    alpha = 1.1
  []
[]
[Variables]
  [pp]
  []
  [frac0]
    initial_condition = 0.1
  []
  [frac1]
    initial_condition = 0.6
  []
[]
[ICs]
  [pp]
    type = FunctionIC
    variable = pp
    function = y
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = frac0
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = frac1
  []
  [mass2]
    type = PorousFlowMassTimeDerivative
    fluid_component = 2
    variable = pp
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 1.3
    density0 = 1.1
    thermal_expansion = 0
    viscosity = 1.1
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = pp
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'frac0 frac1'
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '0.2 0 0 0 0.1 0 0 0 0.1'
  []
  [relperm]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
  []
[]
[AuxVariables]
  [flux_out]
  []
[]
[Postprocessors]
  [f1_00]
    type = PointValue
    point = '0 0 0'
    variable = frac1
    execute_on = 'initial timestep_end'
  []
  [flux_00]
    type = PointValue
    point = '0 0 0'
    variable = flux_out
    execute_on = 'initial timestep_end'
  []
  [p00]
    type = PointValue
    point = '0 0 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [m1_00]
    type = ParsedPostprocessor
    expression = 'f1_00*vol*por*dens0*exp(p00/bulk)*pow(1+pow(-al*p00,1.0/(1-m)),-m)'
    constant_names = 'vol por dens0 bulk al m'
    constant_expressions = '0.25 0.1 1.1 1.3 1.1 0.5'
    pp_names = 'f1_00 p00'
    execute_on = 'initial timestep_end'
  []
  [dm1_00]
    type = ChangeOverTimePostprocessor
    postprocessor = m1_00
    outputs = none
  []
  [m1_00_prev]
    type = ParsedPostprocessor
    expression = 'm1_00 - dm1_00'
    pp_names = 'm1_00 dm1_00'
    outputs = 'console'
  []
  [del_m1_00]
    type = ParsedPostprocessor
    expression = 'f1_00*fcn*area*dt'
    constant_names = 'fcn area dt'
    constant_expressions = '6  0.5  1E-3'
    pp_names = 'f1_00'
    outputs = 'console'
  []
  [m1_00_expect]
    type = ParsedPostprocessor
    expression = 'm1_00_prev-del_m1_00'
    pp_names = 'm1_00_prev del_m1_00'
  []
  [f1_01]
    type = PointValue
    point = '0 1 0'
    variable = frac1
    execute_on = 'initial timestep_end'
  []
  [flux_01]
    type = PointValue
    point = '0 1 0'
    variable = flux_out
    execute_on = 'initial timestep_end'
  []
  [p01]
    type = PointValue
    point = '0 1 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
  [m1_01]
    type = ParsedPostprocessor
    expression = 'f1_01*vol*por*dens0*exp(p01/bulk)*pow(1+pow(-al*p01,1.0/(1-m)),-m)'
    constant_names = 'vol por dens0 bulk al m'
    constant_expressions = '0.25 0.1 1.1 1.3 1.1 0.5'
    pp_names = 'f1_01 p01'
    execute_on = 'initial timestep_end'
  []
  [dm1_01]
    type = ChangeOverTimePostprocessor
    postprocessor = m1_01
    outputs = none
  []
  [m1_01_prev]
    type = ParsedPostprocessor
    expression = 'm1_01 - dm1_01'
    pp_names = 'm1_01 dm1_01'
    outputs = 'console'
  []
  [del_m1_01]
    type = ParsedPostprocessor
    expression = 'f1_01*fcn*area*dt'
    constant_names = 'fcn area dt'
    constant_expressions = '6  0.5  1E-3'
    pp_names = 'f1_01'
    outputs = 'console'
  []
  [m1_01_expect]
    type = ParsedPostprocessor
    expression = 'm1_01_prev-del_m1_01'
    pp_names = 'm1_01_prev del_m1_01'
  []
  [f1_11]
    type = PointValue
    point = '1 1 0'
    variable = frac1
    execute_on = 'initial timestep_end'
  []
  [flux_11]
    type = PointValue
    point = '1 1 0'
    variable = flux_out
    execute_on = 'initial timestep_end'
  []
  [p11]
    type = PointValue
    point = '1 1 0'
    variable = pp
    execute_on = 'initial timestep_end'
  []
[]
[BCs]
  [flux]
    type = PorousFlowSink
    boundary = 'left'
    variable = frac1
    use_mobility = false
    use_relperm = false
    mass_fraction_component = 1
    fluid_phase = 0
    flux_function = 6
    save_in = flux_out
  []
[]
[Preconditioning]
  [andy]
    type = SMP
    full = true
    petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -snes_max_it -sub_pc_factor_shift_type -pc_asm_overlap'
    petsc_options_value = 'gmres asm lu 10 NONZERO 2'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 1E-3
  end_time = 0.01
  nl_rel_tol = 1E-12
  nl_abs_tol = 1E-12
[]
[Outputs]
  file_base = s07
  [console]
    type = Console
    execute_on = 'nonlinear linear'
  []
  [csv]
    type = CSV
    execute_on = 'timestep_end'
  []
[]
(modules/porous_flow/test/tests/hysteresis/1phase_bc.i)
# Simple example of a 1-phase situation with hysteretic capillary pressure.  Water is removed and added to the system in order to observe the hysteresis.  A PorousFlowSink is used to remove and add water.  This input file is analogous to 1phase.i, but uses PorousFlowSink instead of PorousFlowPointSourceFromPostprocessor to remove and add water
[Mesh]
  [mesh]
    type = GeneratedMeshGenerator
    dim = 1
  []
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    number_fluid_phases = 1
    number_fluid_components = 1
    porous_flow_vars = 'pp'
  []
[]
[Variables]
  [pp]
    initial_condition = 0
  []
[]
[Kernels]
  [mass_conservation]
    type = PorousFlowMassTimeDerivative
    variable = pp
  []
[]
[BCs]
  [pump]
    type = PorousFlowSink
    flux_function = '-0.5 * if(t <= 9, -10, 10)'
    boundary = 'left right'
    variable = pp
  []
[]
[AuxVariables]
  [sat]
    family = MONOMIAL
    order = CONSTANT
  []
  [hys_order]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [sat]
    type = PorousFlowPropertyAux
    variable = sat
    property = saturation
  []
  [hys_order]
    type = PorousFlowPropertyAux
    variable = hys_order
    property = hysteresis_order
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
  []
[]
[Materials]
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.1
  []
  [temperature]
    type = PorousFlowTemperature
    temperature = 20
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [hys_order_material]
    type = PorousFlowHysteresisOrder
  []
  [pc_calculator]
    type = PorousFlow1PhaseHysP
    alpha_d = 10.0
    alpha_w = 7.0
    n_d = 1.5
    n_w = 1.9
    S_l_min = 0.1
    S_lr = 0.2
    S_gr_max = 0.3
    Pc_max = 12.0
    high_ratio = 0.9
    low_extension_type = quadratic
    high_extension_type = power
    porepressure = pp
  []
[]
[Postprocessors]
  [flux]
    type = FunctionValuePostprocessor
    function = 'if(t <= 9, -10, 10)'
  []
  [hys_order]
    type = PointValue
    point = '0 0 0'
    variable = hys_order
  []
  [sat]
    type = PointValue
    point = '0 0 0'
    variable = sat
  []
  [pp]
    type = PointValue
    point = '0 0 0'
    variable = pp
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  dt = 0.5
  end_time = 19
  nl_abs_tol = 1E-10
[]
[Outputs]
  csv = true
[]
(modules/porous_flow/test/tests/infiltration_and_drainage/bw02.i)
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 200
  ny = 1
  xmin = -10
  xmax = 10
  ymin = 0
  ymax = 0.05
[]
[GlobalParams]
  PorousFlowDictator = dictator
[]
[Functions]
  [dts]
    type = PiecewiseLinear
    y = '1E-1 5E-1 5E-1'
    x = '0 1 10'
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = pressure
    number_fluid_phases = 1
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureBW
    Sn = 0.0
    Ss = 1.0
    C = 1.5
    las = 2
  []
[]
[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2e9
    viscosity = 4
    density0 = 10
    thermal_expansion = 0
  []
[]
[Materials]
  [massfrac]
    type = PorousFlowMassFraction
  []
  [temperature]
    type = PorousFlowTemperature
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = pressure
    capillary_pressure = pc
  []
  [relperm]
    type = PorousFlowRelativePermeabilityBW
    Sn = 0.0
    Ss = 1.0
    Kn = 0
    Ks = 1
    C = 1.5
    phase = 0
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.25
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1 0 0  0 1 0  0 0 1'
  []
[]
[Variables]
  [pressure]
    initial_condition = -9E2
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pressure
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pressure
    gravity = '-0.1 0 0'
  []
[]
[AuxVariables]
  [SWater]
    family = MONOMIAL
    order = CONSTANT
  []
[]
[AuxKernels]
  [SWater]
    type = MaterialStdVectorAux
    property = PorousFlow_saturation_qp
    index = 0
    variable = SWater
  []
[]
[BCs]
  [recharge]
    type = PorousFlowSink
    variable = pressure
    boundary = right
    flux_function = -1.25 # corresponds to Rstar being 0.5 because i have to multiply by density*porosity
  []
[]
[Preconditioning]
  [andy]
    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               1E-10      1E-10      10000'
  []
[]
[Executioner]
  type = Transient
  solve_type = Newton
  petsc_options = '-snes_converged_reason'
  end_time = 2
  [TimeStepper]
    type = FunctionDT
    function = dts
  []
[]
[VectorPostprocessors]
  [swater]
    type = LineValueSampler
    variable = SWater
    start_point = '-10 0 0'
    end_point = '10 0 0'
    sort_by = x
    num_points = 80
    execute_on = timestep_end
  []
[]
[Outputs]
  file_base = bw02
  sync_times = '0.5 2 8'
  [exodus]
    type = Exodus
    sync_only = true
  []
  [along_line]
    type = CSV
    sync_only = true
  []
[]
(modules/porous_flow/test/tests/sinks/injection_production_eg.i)
# phase = 0 is liquid phase
# phase = 1 is gas phase
# fluid_component = 0 is water
# fluid_component = 1 is CO2
# Constant rate of CO2 injection into the left boundary
# 1D mesh
# The PorousFlowPiecewiseLinearSinks remove the correct water and CO2 from the right boundary
# Note i take pretty big timesteps here so the system is quite nonlinear
[Mesh]
  type = GeneratedMesh
  dim = 1
  nx = 20
  xmax = 20
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[AuxVariables]
  [saturation_gas]
    order = CONSTANT
    family = MONOMIAL
  []
  [frac_water_in_liquid]
    initial_condition = 1.0
  []
  [frac_water_in_gas]
    initial_condition = 0.0
  []
[]
[AuxKernels]
  [saturation_gas]
    type = PorousFlowPropertyAux
    variable = saturation_gas
    property = saturation
    phase = 1
    execute_on = timestep_end
  []
[]
[Variables]
  [pwater]
    initial_condition = 20E6
  []
  [pgas]
    initial_condition = 20.1E6
  []
[]
[Kernels]
  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = pwater
  []
  [flux0]
    type = PorousFlowAdvectiveFlux
    fluid_component = 0
    variable = pwater
  []
  [mass1]
    type = PorousFlowMassTimeDerivative
    fluid_component = 1
    variable = pgas
  []
  [flux1]
    type = PorousFlowAdvectiveFlux
    fluid_component = 1
    variable = pgas
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pgas pwater'
    number_fluid_phases = 2
    number_fluid_components = 2
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    alpha = 1E-6
    m = 0.6
  []
[]
[FluidProperties]
  [true_water]
    type = Water97FluidProperties
  []
  [tabulated_water]
    type = TabulatedBicubicFluidProperties
    fp = true_water
    temperature_min = 275
    pressure_max = 1E8
    interpolated_properties = 'density viscosity enthalpy internal_energy'
    fluid_property_output_file = water97_tabulated_11.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = water97_tabulated_11.csv
  []
  [true_co2]
    type = CO2FluidProperties
  []
  [tabulated_co2]
    type = TabulatedBicubicFluidProperties
    fp = true_co2
    temperature_min = 275
    pressure_max = 1E8
    interpolated_properties = 'density viscosity enthalpy internal_energy'
    fluid_property_output_file = co2_tabulated_11.csv
    # Comment out the fp parameter and uncomment below to use the newly generated tabulation
    # fluid_property_file = co2_tabulated_11.csv
  []
[]
[Materials]
  [temperature]
    type = PorousFlowTemperature
    temperature = 293.15
  []
  [saturation_calculator]
    type = PorousFlow2PhasePP
    phase0_porepressure = pwater
    phase1_porepressure = pgas
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
    mass_fraction_vars = 'frac_water_in_liquid frac_water_in_gas'
  []
  [water]
    type = PorousFlowSingleComponentFluid
    fp = tabulated_water
    phase = 0
  []
  [co2]
    type = PorousFlowSingleComponentFluid
    fp = tabulated_co2
    phase = 1
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.2
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1e-12 0 0 0 1e-12 0 0 0 1e-12'
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
    s_res = 0.1
    sum_s_res = 0.2
  []
  [relperm_gas]
    type = PorousFlowRelativePermeabilityBC
    nw_phase = true
    lambda = 2
    s_res = 0.1
    sum_s_res = 0.2
    phase = 1
  []
[]
[BCs]
  [co2_injection]
    type = PorousFlowSink
    boundary = left
    variable = pgas # pgas is associated with the CO2 mass balance (fluid_component = 1 in its Kernels)
    flux_function = -1E-2 # negative means a source, rather than a sink
  []
  [right_water]
    type = PorousFlowPiecewiseLinearSink
    boundary = right
    # a sink of water, since the Kernels given to pwater are for fluid_component = 0 (the water)
    variable = pwater
    # this Sink is a function of liquid porepressure
    # Also, all the mass_fraction, mobility and relperm are referenced to the liquid phase now
    fluid_phase = 0
    # Sink strength = (Pwater - 20E6)
    pt_vals = '0 1E9'
    multipliers = '0 1E9'
    PT_shift = 20E6
    # multiply Sink strength computed above by mass fraction of water at the boundary
    mass_fraction_component = 0
    # also multiply Sink strength by mobility of the liquid
    use_mobility = true
    # also multiply Sink strength by the relperm of the liquid
    use_relperm = true
    # also multiplly Sink strength by 1/L, where L is the distance to the fixed-porepressure external environment
    flux_function = 10 # 1/L
  []
  [right_co2]
    type = PorousFlowPiecewiseLinearSink
    boundary = right
    variable = pgas
    fluid_phase = 1
    pt_vals = '0 1E9'
    multipliers = '0 1E9'
    PT_shift = 20.1E6
    mass_fraction_component = 1
    use_mobility = true
    use_relperm = true
    flux_function = 10 # 1/L
  []
[]
[Preconditioning]
  active = 'basic'
  [basic]
    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'
    petsc_options_value = 'gmres asm lu NONZERO 2'
  []
  [preferred]
    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
  nl_abs_tol = 1E-13
  nl_rel_tol = 1E-10
  end_time = 1e4
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 1E4
    growth_factor = 1.1
  []
[]
[VectorPostprocessors]
  [pps]
    type = LineValueSampler
    warn_discontinuous_face_values = false
    start_point = '0 0 0'
    end_point = '20 0 0'
    num_points = 20
    sort_by = x
    variable = 'pgas pwater saturation_gas'
  []
[]
[Outputs]
  print_linear_residuals = false
  perf_graph = true
  [out]
    type = CSV
    execute_on = final
  []
[]
(modules/porous_flow/test/tests/fluidstate/coldwater_injection_radial.i)
# Cold water injection into 1D radial hot reservoir (Avdonin, 1964)
#
# To generate results presented in documentation for this problem,
# set xmax = 1000 and nx = 200 in the Mesh block, and dtmax = 1e4
# and end_time = 1e6 in the Executioner block.
[Mesh]
  type = GeneratedMesh
  dim = 1
  nx = 50
  xmin = 0.1
  xmax = 5
  bias_x = 1.05
  rz_coord_axis = Y
  coord_type = RZ
[]
[GlobalParams]
  PorousFlowDictator = dictator
  gravity = '0 0 0'
[]
[AuxVariables]
  [temperature]
    order = CONSTANT
    family = MONOMIAL
  []
[]
[AuxKernels]
  [temperature]
    type = PorousFlowPropertyAux
    variable = temperature
    property = temperature
    execute_on = 'initial timestep_end'
  []
[]
[Variables]
  [pliquid]
    initial_condition = 5e6
  []
  [h]
    scaling = 1e-6
  []
[]
[ICs]
  [hic]
    type = PorousFlowFluidPropertyIC
    variable = h
    porepressure = pliquid
    property = enthalpy
    temperature = 170
    temperature_unit = Celsius
    fp = water
  []
[]
[Functions]
  [injection_rate]
    type = ParsedFunction
    symbol_values = injection_area
    symbol_names = area
    expression = '-0.1/area'
  []
[]
[BCs]
  [source]
    type = PorousFlowSink
    variable = pliquid
    flux_function = injection_rate
    boundary = left
  []
  [pright]
    type = DirichletBC
    variable = pliquid
    value = 5e6
    boundary = right
  []
  [hleft]
    type = DirichletBC
    variable = h
    value = 678.52e3
    boundary = left
  []
  [hright]
    type = DirichletBC
    variable = h
    value = 721.4e3
    boundary = right
  []
[]
[Kernels]
  [mass]
    type = PorousFlowMassTimeDerivative
    variable = pliquid
  []
  [massflux]
    type = PorousFlowAdvectiveFlux
    variable = pliquid
  []
  [heat]
    type = PorousFlowEnergyTimeDerivative
    variable = h
  []
  [heatflux]
    type = PorousFlowHeatAdvection
    variable = h
  []
  [heatcond]
    type = PorousFlowHeatConduction
    variable = h
  []
[]
[UserObjects]
  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'pliquid h'
    number_fluid_phases = 2
    number_fluid_components = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureVG
    pc_max = 1e6
    sat_lr = 0.1
    m = 0.5
    alpha = 1e-5
  []
  [fs]
    type = PorousFlowWaterVapor
    water_fp = water
    capillary_pressure = pc
  []
[]
[FluidProperties]
  [water]
    type = Water97FluidProperties
  []
[]
[Materials]
  [watervapor]
    type = PorousFlowFluidStateSingleComponent
    porepressure = pliquid
    enthalpy = h
    temperature_unit = Celsius
    capillary_pressure = pc
    fluid_state = fs
  []
  [porosity]
    type = PorousFlowPorosityConst
    porosity = 0.2
  []
  [permeability]
    type = PorousFlowPermeabilityConst
    permeability = '1.8e-11 0 0 0 1.8e-11 0 0 0 1.8e-11'
  []
  [relperm_water]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 0
    s_res = 0.1
    sum_s_res = 0.1
  []
  [relperm_gas]
    type = PorousFlowRelativePermeabilityCorey
    n = 2
    phase = 1
    sum_s_res = 0.1
  []
  [internal_energy]
    type = PorousFlowMatrixInternalEnergy
    density = 2900
    specific_heat_capacity = 740
  []
  [rock_thermal_conductivity]
    type = PorousFlowThermalConductivityIdeal
    dry_thermal_conductivity = '20 0 0  0 20 0  0 0 20'
  []
[]
[Preconditioning]
  [smp]
    type = SMP
    full = true
  []
[]
[Executioner]
  type = Transient
  solve_type = NEWTON
  end_time = 1e3
  nl_abs_tol = 1e-8
  [TimeStepper]
    type = IterationAdaptiveDT
    dt = 100
  []
[]
[Postprocessors]
  [injection_area]
    type = AreaPostprocessor
    boundary = left
    execute_on = initial
  []
[]
[VectorPostprocessors]
  [line]
    type = ElementValueSampler
    sort_by = x
    variable = temperature
    execute_on = 'initial timestep_end'
  []
[]
[Outputs]
  perf_graph = true
  [csv]
    type = CSV
    execute_on = final
  []
[]
(modules/porous_flow/include/bcs/PorousFlowSinkPTDefiner.h)
// This file is part of the MOOSE framework
// https://mooseframework.inl.gov
//
// All rights reserved, see COPYRIGHT for full restrictions
// https://github.com/idaholab/moose/blob/master/COPYRIGHT
//
// Licensed under LGPL 2.1, please see LICENSE for details
// https://www.gnu.org/licenses/lgpl-2.1.html
#pragma once
#include "PorousFlowSink.h"
/**
 * Provides either a porepressure or a temperature
 * to derived classes, depending on _involves_fluid
 * defined in PorousFlowSink
 */
class PorousFlowSinkPTDefiner : public PorousFlowSink
{
public:
  static InputParameters validParams();
  PorousFlowSinkPTDefiner(const InputParameters & parameters);
protected:
  /// Nodal pore pressure in each phase
  const MaterialProperty<std::vector<Real>> * const _pp;
  /// d(Nodal pore pressure in each phase)/d(PorousFlow variable)
  const MaterialProperty<std::vector<std::vector<Real>>> * const _dpp_dvar;
  /// Nodal temperature
  const MaterialProperty<Real> * const _temp;
  /// d(Nodal temperature)/d(PorousFlow variable)
  const MaterialProperty<std::vector<Real>> * const _dtemp_dvar;
  /// Subtract this from porepressure or temperature before evaluating PiecewiseLinearSink, HalfCubicSink, etc
  const VariableValue & _pt_shift;
  /// Provides the variable value (either porepressure, or temperature, depending on _involves_fluid)
  virtual Real ptVar() const;
  /// Provides the d(variable)/(d PorousFlow Variable pvar)
  virtual Real dptVar(unsigned pvar) const;
};