Simulating underground coal mining

Introduction

In an underground longwall coal mine, coal is mined in "panels", as shown in Figure 1. These panels are typically 3–4m in height, 150–400m in width and 1000–4000m long. Coal is extracted from one end, moving towards the other end. As mining progresses, a void is created behind the mining machinery where the coal used to be. The rock material above this void— the "overburden"—is not strong enough to support itself, so it collapses downwards. The resulting partial void and collapsed material is called the "goaf" (or "gob").

Figure 1: Pictorial representation of a single panel in longwall mining. The dimensions and process are described in the text. Figure sourced from citizensagainstlongwallmining.org who obtained it from the Energy Information Administration.

There are many geotechnical aspects that are of interest in this process, but this Example concentrates on the following.

  1. The vertical displacement of the ground surface due to the longwall mining. This is called the "subsidence". This obviously has effects on buildings and other man-made structures like roads, but it can also change surface water pathways, affect vegetation, and cause surface-water ponding, which all have effects on the local ecology.

  2. The vertical deformation within the overburden.

  3. The patterns of fracture in the overburden. Together with the previous item, this can have effects on operational aspects of longwall mining, such as the load patterns on the "chocks" that support the roof of the goaf next to the mining machinery. It also strongly effects the flow of fluids in the porous rocks that make up the overburden, as discussed next.

  4. The flow of water through the rock. If the fracturing and deformation is extensive then fluids can easily move through the rock. This can result in mines flooding with water, or causing excessive drawdown of groundwater aquifers which can effect other users of groundwater (such as irrigators for farming) or can effect the rates of groundwater baseflow to surrounding river systems which may effect local and not-so-local ecosystems. The deformation and fracture of the overburden can also lead to aquifer mixing, where an aquifer consisting of "dirty" water (with high salinity, for example) pollutes a nearby aquifer of clean water. Although not studied in this Example, the deformation and fracture can also lead to large releases of methane gas from overlying (and underlying) coal seams. This methane can then flow through the highly permeable fractured rock system to the atmosphere, resulting in large greenhouse gas emissions. Or it can flow to the mine workings which is extremely hazardous in terms of mine fires and explosions.

This Example does not seek to build a realistic model of a specific mine. Instead, it explains how the PorousFlow module can be used to build such a model, by exploring a simple 3D model.

The model

Two input files are provided with this example: coarse_with_fluid.i and fine_with_fluid.i. They essentially only differ in the input mesh. The results below are drawn from the fine model, but it takes a few hours to complete on a computer cluster, so the coarse model might be a better model to explore initially.

Geometry

Figure 2 shows the geometrical setup as well as the fine mesh. The model represents a single longwall panel of total width 300m and length 1000m. Only half of the width is modelled, and appropriate boundary conditions used to simulate the full panel. In the fine model, the panel is meshed with 10m square elements.

Figure 2: The geometry of the model and the mesh used. A single longwall panel of total width 300m and length 1000m is represented by the region with a fine mesh.

Fluid mechanics

Single-phase unsaturated fluid is used with the nonlinear Variable being the fluid porepressure. Full coupling with mechanical deformations is used, so the Kernels read

  [mass0]
    type = PorousFlowMassTimeDerivative
    fluid_component = 0
    variable = porepressure
  []
  [flux]
    type = PorousFlowAdvectiveFlux
    use_displaced_mesh = false
    variable = porepressure
    gravity = '0 0 -10E-6'
    fluid_component = 0
  []
  [poro_vol_exp]
    type = PorousFlowMassVolumetricExpansion
    block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    variable = porepressure
    fluid_component = 0
  []
[]
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

All stresses are measured in MPa and the time unit is years. A Biot coefficient of 0.7 is used, and the fluid properties are:

# Strata deformation and fluid flow aaround a coal mine - 3D model
#
# A "half model" is used.  The mine is 400m deep and
# just the roof is studied (-400<=z<=0).  The mining panel
# sits between 0<=x<=150, and 0<=y<=1000, so this simulates
# a coal panel that is 300m wide and 1000m long.  The outer boundaries
# are 1km from the excavation boundaries.
#
# The excavation takes 0.5 years.
#
# The boundary conditions for this simulation are:
#  - disp_x = 0 at x=0 and x=1150
#  - disp_y = 0 at y=-1000 and y=1000
#  - disp_z = 0 at z=-400, but there is a time-dependent
#               Young modulus that simulates excavation
#  - wc_x = 0 at y=-1000 and y=1000
#  - wc_y = 0 at x=0 and x=1150
#  - no flow at x=0, z=-400 and z=0
#  - fixed porepressure at y=-1000, y=1000 and x=1150
# That is, rollers on the sides, free at top,
# and prescribed at bottom in the unexcavated portion.
#
# A single-phase unsaturated fluid is used.
#
# The small strain formulation is used.
#
# All stresses are measured in MPa, and time units are measured in years.
#
# The initial porepressure is hydrostatic with P=0 at z=0, so
# Porepressure ~ - 0.01*z MPa, where the fluid has density 1E3 kg/m^3 and
# gravity = = 10 m.s^-2 = 1E-5 MPa m^2/kg.
# To be more accurate, i use
# Porepressure = -bulk * log(1 + g*rho0*z/bulk)
# where bulk=2E3 MPa and rho0=1Ee kg/m^3.
# The initial stress is consistent with the weight force from undrained
# density 2500 kg/m^3, and fluid porepressure, and a Biot coefficient of 0.7, ie,
# stress_zz^effective = 0.025*z + 0.7 * initial_porepressure
# The maximum and minimum principal horizontal effective stresses are
# assumed to be equal to 0.8*stress_zz.
#
# Material properties:
# Young's modulus = 8 GPa
# Poisson's ratio = 0.25
# Cosserat layer thickness = 1 m
# Cosserat-joint normal stiffness = large
# Cosserat-joint shear stiffness = 1 GPa
# MC cohesion = 2 MPa
# MC friction angle = 35 deg
# MC dilation angle = 8 deg
# MC tensile strength = 1 MPa
# MC compressive strength = 100 MPa
# WeakPlane cohesion = 0.1 MPa
# WeakPlane friction angle = 30 deg
# WeakPlane dilation angle = 10 deg
# WeakPlane tensile strength = 0.1 MPa
# WeakPlane compressive strength = 100 MPa softening to 1 MPa at strain = 1
# Fluid density at zero porepressure = 1E3 kg/m^3
# Fluid bulk modulus = 2E3 MPa
# Fluid viscosity = 1.1E-3 Pa.s = 1.1E-9 MPa.s = 3.5E-17 MPa.year
#
[GlobalParams<<<{"href": "../../syntax/GlobalParams/index.html"}>>>]
  perform_finite_strain_rotations = false
  displacements = 'disp_x disp_y disp_z'
  Cosserat_rotations = 'wc_x wc_y wc_z'
  PorousFlowDictator = dictator
  biot_coefficient = 0.7
[]

[Mesh<<<{"href": "../../syntax/Mesh/index.html"}>>>]
  [file]
    type = FileMeshGenerator<<<{"description": "Read a mesh from a file.", "href": "../../source/meshgenerators/FileMeshGenerator.html"}>>>
    file<<<{"description": "The filename to read."}>>> = mesh/coarse.e
  []
  [xmin]
    type = SideSetsAroundSubdomainGenerator<<<{"description": "Adds element faces that are on the exterior of the given block to the sidesets specified", "href": "../../source/meshgenerators/SideSetsAroundSubdomainGenerator.html"}>>>
     block<<<{"description": "The blocks around which to create sidesets"}>>> = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = xmin
    normal<<<{"description": "If supplied, only faces with normal equal to this, up to normal_tol, will be added to the sidesets specified"}>>> = '-1 0 0'
    input<<<{"description": "The mesh we want to modify"}>>> = file
  []
  [xmax]
    type = SideSetsAroundSubdomainGenerator<<<{"description": "Adds element faces that are on the exterior of the given block to the sidesets specified", "href": "../../source/meshgenerators/SideSetsAroundSubdomainGenerator.html"}>>>
     block<<<{"description": "The blocks around which to create sidesets"}>>> = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = xmax
    normal<<<{"description": "If supplied, only faces with normal equal to this, up to normal_tol, will be added to the sidesets specified"}>>> = '1 0 0'
    input<<<{"description": "The mesh we want to modify"}>>> = xmin
  []
  [ymin]
    type = SideSetsAroundSubdomainGenerator<<<{"description": "Adds element faces that are on the exterior of the given block to the sidesets specified", "href": "../../source/meshgenerators/SideSetsAroundSubdomainGenerator.html"}>>>
     block<<<{"description": "The blocks around which to create sidesets"}>>> = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = ymin
    normal<<<{"description": "If supplied, only faces with normal equal to this, up to normal_tol, will be added to the sidesets specified"}>>> = '0 -1 0'
    input<<<{"description": "The mesh we want to modify"}>>> = xmax
  []
  [ymax]
    type = SideSetsAroundSubdomainGenerator<<<{"description": "Adds element faces that are on the exterior of the given block to the sidesets specified", "href": "../../source/meshgenerators/SideSetsAroundSubdomainGenerator.html"}>>>
     block<<<{"description": "The blocks around which to create sidesets"}>>> = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = ymax
    normal<<<{"description": "If supplied, only faces with normal equal to this, up to normal_tol, will be added to the sidesets specified"}>>> = '0 1 0'
    input<<<{"description": "The mesh we want to modify"}>>> = ymin
  []
  [zmax]
    type = SideSetsAroundSubdomainGenerator<<<{"description": "Adds element faces that are on the exterior of the given block to the sidesets specified", "href": "../../source/meshgenerators/SideSetsAroundSubdomainGenerator.html"}>>>
    block<<<{"description": "The blocks around which to create sidesets"}>>> = 16
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = zmax
    normal<<<{"description": "If supplied, only faces with normal equal to this, up to normal_tol, will be added to the sidesets specified"}>>> = '0 0 1'
    input<<<{"description": "The mesh we want to modify"}>>> = ymax
  []
  [zmin]
    type = SideSetsAroundSubdomainGenerator<<<{"description": "Adds element faces that are on the exterior of the given block to the sidesets specified", "href": "../../source/meshgenerators/SideSetsAroundSubdomainGenerator.html"}>>>
    block<<<{"description": "The blocks around which to create sidesets"}>>> = 2
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = zmin
    normal<<<{"description": "If supplied, only faces with normal equal to this, up to normal_tol, will be added to the sidesets specified"}>>> = '0 0 -1'
    input<<<{"description": "The mesh we want to modify"}>>> = zmax
  []
  [excav]
    type = SubdomainBoundingBoxGenerator<<<{"description": "Changes the subdomain ID of elements either (XOR) inside or outside the specified box to the specified ID.", "href": "../../source/meshgenerators/SubdomainBoundingBoxGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = zmin
    block_id<<<{"description": "Subdomain id to set for inside/outside the bounding box"}>>> = 1
    bottom_left<<<{"description": "The bottom left point (in x,y,z with spaces in-between)."}>>> = '0 0 -400'
    top_right<<<{"description": "The bottom left point (in x,y,z with spaces in-between)."}>>> = '150 1000 -397'
  []
  [roof]
    type = SideSetsBetweenSubdomainsGenerator<<<{"description": "MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains.", "href": "../../source/meshgenerators/SideSetsBetweenSubdomainsGenerator.html"}>>>
    primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = 3
    paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = 1
    input<<<{"description": "The mesh we want to modify"}>>> = excav
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = roof
  []
[]

[Variables<<<{"href": "../../syntax/Variables/index.html"}>>>]
  [disp_x]
  []
  [disp_y]
  []
  [disp_z]
  []
  [wc_x]
  []
  [wc_y]
  []
  [porepressure]
    scaling<<<{"description": "Specifies a scaling factor to apply to this variable"}>>> = 1E-5
  []
[]

[ICs<<<{"href": "../../syntax/ICs/index.html"}>>>]
  [porepressure]
    type = FunctionIC<<<{"description": "An initial condition that uses a normal function of x, y, z to produce values (and optionally gradients) for a field variable.", "href": "../../source/ics/FunctionIC.html"}>>>
    variable<<<{"description": "The variable this initial condition is supposed to provide values for."}>>> = porepressure
    function<<<{"description": "The initial condition function."}>>> = ini_pp
  []
[]

[Kernels<<<{"href": "../../syntax/Kernels/index.html"}>>>]
  [cx_elastic]
    type = CosseratStressDivergenceTensors<<<{"description": "Stress divergence tensor with the additional Jacobian terms for the Cosserat rotation variables.", "href": "../../source/kernels/CosseratStressDivergenceTensors.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_x
    component<<<{"description": "An integer corresponding to the direction the variable this kernel acts in. (0 for x, 1 for y, 2 for z)"}>>> = 0
  []
  [cy_elastic]
    type = CosseratStressDivergenceTensors<<<{"description": "Stress divergence tensor with the additional Jacobian terms for the Cosserat rotation variables.", "href": "../../source/kernels/CosseratStressDivergenceTensors.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_y
    component<<<{"description": "An integer corresponding to the direction the variable this kernel acts in. (0 for x, 1 for y, 2 for z)"}>>> = 1
  []
  [cz_elastic]
    type = CosseratStressDivergenceTensors<<<{"description": "Stress divergence tensor with the additional Jacobian terms for the Cosserat rotation variables.", "href": "../../source/kernels/CosseratStressDivergenceTensors.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_z
    component<<<{"description": "An integer corresponding to the direction the variable this kernel acts in. (0 for x, 1 for y, 2 for z)"}>>> = 2
  []
  [x_couple]
    type = StressDivergenceTensors<<<{"description": "Stress divergence kernel for the Cartesian coordinate system", "href": "../../source/kernels/StressDivergenceTensors.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = wc_x
    displacements<<<{"description": "The string of displacements suitable for the problem statement"}>>> = 'wc_x wc_y wc_z'
    component<<<{"description": "An integer corresponding to the direction the variable this kernel acts in. (0 for x, 1 for y, 2 for z)"}>>> = 0
    base_name<<<{"description": "Material property base name"}>>> = couple
  []
  [y_couple]
    type = StressDivergenceTensors<<<{"description": "Stress divergence kernel for the Cartesian coordinate system", "href": "../../source/kernels/StressDivergenceTensors.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = wc_y
    displacements<<<{"description": "The string of displacements suitable for the problem statement"}>>> = 'wc_x wc_y wc_z'
    component<<<{"description": "An integer corresponding to the direction the variable this kernel acts in. (0 for x, 1 for y, 2 for z)"}>>> = 1
    base_name<<<{"description": "Material property base name"}>>> = couple
  []
  [x_moment]
    type = MomentBalancing<<<{"description": "Balance of momentum for three-dimensional Cosserat media, notably in a Cosserat layered elasticity model.", "href": "../../source/kernels/MomentBalancing.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = wc_x
    component<<<{"description": "An integer corresponding to the direction the variable this kernel acts in. (0 for x, 1 for y, 2 for z)"}>>> = 0
  []
  [y_moment]
    type = MomentBalancing<<<{"description": "Balance of momentum for three-dimensional Cosserat media, notably in a Cosserat layered elasticity model.", "href": "../../source/kernels/MomentBalancing.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = wc_y
    component<<<{"description": "An integer corresponding to the direction the variable this kernel acts in. (0 for x, 1 for y, 2 for z)"}>>> = 1
  []
  [gravity]
    type = Gravity<<<{"description": "Apply gravity. Value is in units of acceleration.", "href": "../../source/kernels/Gravity.html"}>>>
    use_displaced_mesh<<<{"description": "Displaced mesh defaults to true"}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_z
    value<<<{"description": "Value multiplied against the residual, e.g. gravitational acceleration"}>>> = -10E-6 # remember this is in MPa
  []
  [poro_x]
    type = PorousFlowEffectiveStressCoupling<<<{"description": "Implements the weak form of the expression biot_coefficient * grad(effective fluid pressure)", "href": "../../source/kernels/PorousFlowEffectiveStressCoupling.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_x
    component<<<{"description": "The component (0 for x, 1 for y and 2 for z) of grad(P)"}>>> = 0
  []
  [poro_y]
    type = PorousFlowEffectiveStressCoupling<<<{"description": "Implements the weak form of the expression biot_coefficient * grad(effective fluid pressure)", "href": "../../source/kernels/PorousFlowEffectiveStressCoupling.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_y
    component<<<{"description": "The component (0 for x, 1 for y and 2 for z) of grad(P)"}>>> = 1
  []
  [poro_z]
    type = PorousFlowEffectiveStressCoupling<<<{"description": "Implements the weak form of the expression biot_coefficient * grad(effective fluid pressure)", "href": "../../source/kernels/PorousFlowEffectiveStressCoupling.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    component<<<{"description": "The component (0 for x, 1 for y and 2 for z) of grad(P)"}>>> = 2
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_z
  []
  [mass0]
    type = PorousFlowMassTimeDerivative<<<{"description": "Derivative of fluid-component mass with respect to time.  Mass lumping to the nodes is used.", "href": "../../source/kernels/PorousFlowMassTimeDerivative.html"}>>>
    fluid_component<<<{"description": "The index corresponding to the component for this kernel"}>>> = 0
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = porepressure
  []
  [flux]
    type = PorousFlowAdvectiveFlux<<<{"description": "Fully-upwinded advective flux of the component given by fluid_component", "href": "../../source/kernels/PorousFlowAdvectiveFlux.html"}>>>
    use_displaced_mesh<<<{"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."}>>> = false
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = porepressure
    gravity<<<{"description": "Gravitational acceleration vector downwards (m/s^2)"}>>> = '0 0 -10E-6'
    fluid_component<<<{"description": "The index corresponding to the fluid component for this kernel"}>>> = 0
  []
  [poro_vol_exp]
    type = PorousFlowMassVolumetricExpansion<<<{"description": "Component_mass*rate_of_solid_volumetric_expansion.  This Kernel lumps the component mass to the nodes.", "href": "../../source/kernels/PorousFlowMassVolumetricExpansion.html"}>>>
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = porepressure
    fluid_component<<<{"description": "The index corresponding to the component for this kernel"}>>> = 0
  []
[]

[AuxVariables<<<{"href": "../../syntax/AuxVariables/index.html"}>>>]
  [saturation]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [darcy_x]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [darcy_y]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [darcy_z]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [porosity]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [wc_z]
  []
  [stress_xx]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [stress_xy]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [stress_xz]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [stress_yx]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [stress_yy]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [stress_yz]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [stress_zx]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [stress_zy]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [stress_zz]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_xx]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_xy]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_xz]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_yx]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_yy]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_yz]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_zx]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_zy]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [total_strain_zz]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [perm_xx]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [perm_yy]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [perm_zz]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [mc_shear]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [mc_tensile]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [wp_shear]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [wp_tensile]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [wp_shear_f]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [wp_tensile_f]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [mc_shear_f]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
  [mc_tensile_f]
    order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = CONSTANT
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
  []
[]

[AuxKernels<<<{"href": "../../syntax/AuxKernels/index.html"}>>>]
  [saturation_water]
    type = PorousFlowPropertyAux<<<{"description": "AuxKernel to provide access to properties evaluated at quadpoints. Note that elemental AuxVariables must be used, so that these properties are integrated over each element.", "href": "../../source/auxkernels/PorousFlowPropertyAux.html"}>>>
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = saturation
    property<<<{"description": "The fluid property that this auxillary kernel is to calculate"}>>> = saturation
    phase<<<{"description": "The index of the phase this auxillary kernel acts on"}>>> = 0
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [darcy_x]
    type = PorousFlowDarcyVelocityComponent<<<{"description": "Darcy velocity (in m^3.s^-1.m^-2, or m.s^-1)  -(k_ij * krel /mu (nabla_j P - w_j)), where k_ij is the permeability tensor, krel is the relative permeability, mu is the fluid viscosity, P is the fluid pressure, and w_j is the fluid weight.", "href": "../../source/auxkernels/PorousFlowDarcyVelocityComponent.html"}>>>
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = darcy_x
    gravity<<<{"description": "Gravitational acceleration vector downwards (m/s^2)"}>>> = '0 0 -10E-6'
    component<<<{"description": "The spatial component of the Darcy flux to return"}>>> = x
  []
  [darcy_y]
    type = PorousFlowDarcyVelocityComponent<<<{"description": "Darcy velocity (in m^3.s^-1.m^-2, or m.s^-1)  -(k_ij * krel /mu (nabla_j P - w_j)), where k_ij is the permeability tensor, krel is the relative permeability, mu is the fluid viscosity, P is the fluid pressure, and w_j is the fluid weight.", "href": "../../source/auxkernels/PorousFlowDarcyVelocityComponent.html"}>>>
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = darcy_y
    gravity<<<{"description": "Gravitational acceleration vector downwards (m/s^2)"}>>> = '0 0 -10E-6'
    component<<<{"description": "The spatial component of the Darcy flux to return"}>>> = y
  []
  [darcy_z]
    type = PorousFlowDarcyVelocityComponent<<<{"description": "Darcy velocity (in m^3.s^-1.m^-2, or m.s^-1)  -(k_ij * krel /mu (nabla_j P - w_j)), where k_ij is the permeability tensor, krel is the relative permeability, mu is the fluid viscosity, P is the fluid pressure, and w_j is the fluid weight.", "href": "../../source/auxkernels/PorousFlowDarcyVelocityComponent.html"}>>>
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = darcy_z
    gravity<<<{"description": "Gravitational acceleration vector downwards (m/s^2)"}>>> = '0 0 -10E-6'
    component<<<{"description": "The spatial component of the Darcy flux to return"}>>> = z
  []
  [porosity]
    type = PorousFlowPropertyAux<<<{"description": "AuxKernel to provide access to properties evaluated at quadpoints. Note that elemental AuxVariables must be used, so that these properties are integrated over each element.", "href": "../../source/auxkernels/PorousFlowPropertyAux.html"}>>>
    property<<<{"description": "The fluid property that this auxillary kernel is to calculate"}>>> = porosity
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = porosity
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_xx]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_xx
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 0
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 0
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_xy]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_xy
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 0
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 1
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_xz]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_xz
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 0
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 2
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_yx]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_yx
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 1
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 0
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_yy]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_yy
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 1
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 1
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_yz]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_yz
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 1
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 2
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_zx]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_zx
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 2
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 0
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_zy]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_zy
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 2
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 1
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [stress_zz]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_zz
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 2
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 2
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_xx]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_xx
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 0
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 0
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_xy]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_xy
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 0
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 1
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_xz]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_xz
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 0
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 2
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_yx]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_yx
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 1
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 0
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_yy]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_yy
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 1
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 1
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_yz]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_yz
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 1
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 2
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_zx]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_zx
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 2
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 0
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_zy]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_zy
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 2
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 1
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [total_strain_zz]
    type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../source/auxkernels/RankTwoAux.html"}>>>
    rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = total_strain
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = total_strain_zz
    index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 2
    index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 2
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [perm_xx]
    type = PorousFlowPropertyAux<<<{"description": "AuxKernel to provide access to properties evaluated at quadpoints. Note that elemental AuxVariables must be used, so that these properties are integrated over each element.", "href": "../../source/auxkernels/PorousFlowPropertyAux.html"}>>>
    property<<<{"description": "The fluid property that this auxillary kernel is to calculate"}>>> = permeability
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = perm_xx
    row<<<{"description": "Row of permeability tensor to output"}>>> = 0
    column<<<{"description": "Column of permeability tensor to output"}>>> = 0
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [perm_yy]
    type = PorousFlowPropertyAux<<<{"description": "AuxKernel to provide access to properties evaluated at quadpoints. Note that elemental AuxVariables must be used, so that these properties are integrated over each element.", "href": "../../source/auxkernels/PorousFlowPropertyAux.html"}>>>
    property<<<{"description": "The fluid property that this auxillary kernel is to calculate"}>>> = permeability
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = perm_yy
    row<<<{"description": "Row of permeability tensor to output"}>>> = 1
    column<<<{"description": "Column of permeability tensor to output"}>>> = 1
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [perm_zz]
    type = PorousFlowPropertyAux<<<{"description": "AuxKernel to provide access to properties evaluated at quadpoints. Note that elemental AuxVariables must be used, so that these properties are integrated over each element.", "href": "../../source/auxkernels/PorousFlowPropertyAux.html"}>>>
    property<<<{"description": "The fluid property that this auxillary kernel is to calculate"}>>> = permeability
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = perm_zz
    row<<<{"description": "Row of permeability tensor to output"}>>> = 2
    column<<<{"description": "Column of permeability tensor to output"}>>> = 2
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [mc_shear]
    type = MaterialStdVectorAux<<<{"description": "Extracts a component of a material type std::vector<Real> to an aux variable.  If the std::vector is not of sufficient size then zero is returned", "href": "../../source/auxkernels/MaterialStdVectorAux.html"}>>>
    index<<<{"description": "The index to consider for this kernel"}>>> = 0
    property<<<{"description": "The material property name."}>>> = mc_plastic_internal_parameter
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = mc_shear
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [mc_tensile]
    type = MaterialStdVectorAux<<<{"description": "Extracts a component of a material type std::vector<Real> to an aux variable.  If the std::vector is not of sufficient size then zero is returned", "href": "../../source/auxkernels/MaterialStdVectorAux.html"}>>>
    index<<<{"description": "The index to consider for this kernel"}>>> = 1
    property<<<{"description": "The material property name."}>>> = mc_plastic_internal_parameter
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = mc_tensile
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [wp_shear]
    type = MaterialStdVectorAux<<<{"description": "Extracts a component of a material type std::vector<Real> to an aux variable.  If the std::vector is not of sufficient size then zero is returned", "href": "../../source/auxkernels/MaterialStdVectorAux.html"}>>>
    index<<<{"description": "The index to consider for this kernel"}>>> = 0
    property<<<{"description": "The material property name."}>>> = wp_plastic_internal_parameter
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = wp_shear
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [wp_tensile]
    type = MaterialStdVectorAux<<<{"description": "Extracts a component of a material type std::vector<Real> to an aux variable.  If the std::vector is not of sufficient size then zero is returned", "href": "../../source/auxkernels/MaterialStdVectorAux.html"}>>>
    index<<<{"description": "The index to consider for this kernel"}>>> = 1
    property<<<{"description": "The material property name."}>>> = wp_plastic_internal_parameter
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = wp_tensile
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [mc_shear_f]
    type = MaterialStdVectorAux<<<{"description": "Extracts a component of a material type std::vector<Real> to an aux variable.  If the std::vector is not of sufficient size then zero is returned", "href": "../../source/auxkernels/MaterialStdVectorAux.html"}>>>
    index<<<{"description": "The index to consider for this kernel"}>>> = 6
    property<<<{"description": "The material property name."}>>> = mc_plastic_yield_function
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = mc_shear_f
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [mc_tensile_f]
    type = MaterialStdVectorAux<<<{"description": "Extracts a component of a material type std::vector<Real> to an aux variable.  If the std::vector is not of sufficient size then zero is returned", "href": "../../source/auxkernels/MaterialStdVectorAux.html"}>>>
    index<<<{"description": "The index to consider for this kernel"}>>> = 0
    property<<<{"description": "The material property name."}>>> = mc_plastic_yield_function
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = mc_tensile_f
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [wp_shear_f]
    type = MaterialStdVectorAux<<<{"description": "Extracts a component of a material type std::vector<Real> to an aux variable.  If the std::vector is not of sufficient size then zero is returned", "href": "../../source/auxkernels/MaterialStdVectorAux.html"}>>>
    index<<<{"description": "The index to consider for this kernel"}>>> = 0
    property<<<{"description": "The material property name."}>>> = wp_plastic_yield_function
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = wp_shear_f
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
  [wp_tensile_f]
    type = MaterialStdVectorAux<<<{"description": "Extracts a component of a material type std::vector<Real> to an aux variable.  If the std::vector is not of sufficient size then zero is returned", "href": "../../source/auxkernels/MaterialStdVectorAux.html"}>>>
    index<<<{"description": "The index to consider for this kernel"}>>> = 1
    property<<<{"description": "The material property name."}>>> = wp_plastic_yield_function
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = wp_tensile_f
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = timestep_end
  []
[]

[BCs<<<{"href": "../../syntax/BCs/index.html"}>>>]
  [no_x]
    type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../source/bcs/DirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_x
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'xmin xmax'
    value<<<{"description": "Value of the BC"}>>> = 0.0
  []
  [no_y]
    type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../source/bcs/DirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_y
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ymin ymax'
    value<<<{"description": "Value of the BC"}>>> = 0.0
  []
  [no_z]
    type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../source/bcs/DirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_z
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = zmin
    value<<<{"description": "Value of the BC"}>>> = 0.0
  []
  [no_wc_x]
    type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../source/bcs/DirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = wc_x
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ymin ymax'
    value<<<{"description": "Value of the BC"}>>> = 0.0
  []
  [no_wc_y]
    type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../source/bcs/DirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = wc_y
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'xmin xmax'
    value<<<{"description": "Value of the BC"}>>> = 0.0
  []
  [fix_porepressure]
    type = FunctionDirichletBC<<<{"description": "Imposes the essential boundary condition $u=g(t,\\vec{x})$, where $g$ is a (possibly) time and space-dependent MOOSE Function.", "href": "../../source/bcs/FunctionDirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = porepressure
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ymin ymax xmax'
    function<<<{"description": "The forcing function."}>>> = ini_pp
  []
  [roof_porepressure]
    type = PorousFlowPiecewiseLinearSink<<<{"description": "Applies a flux sink to a boundary. The base flux defined by PorousFlowSink is multiplied by a piecewise linear function.", "href": "../../source/bcs/PorousFlowPiecewiseLinearSink.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = porepressure
    pt_vals<<<{"description": "Tuple of pressure values (for the fluid_phase specified).  Must be monotonically increasing.  For heat fluxes that don't involve fluids, these are temperature values"}>>> = '-1E3 1E3'
    multipliers<<<{"description": "Tuple of multiplying values.  The flux values are multiplied by these."}>>> = '-1 1'
    fluid_phase<<<{"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"}>>> = 0
    flux_function<<<{"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)"}>>> = roof_conductance
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = roof
  []
  [roof_bcs]
    type = StickyBC<<<{"description": "Imposes the boundary condition $u = u_{old}$ if $u_{old}$ exceeds the bounds provided", "href": "../../source/bcs/StickyBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_z
    min_value<<<{"description": "If the old variable value <= min_value, the variable is fixed at its old value"}>>> = -3.0
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = roof
  []
[]

[Functions<<<{"href": "../../syntax/Functions/index.html"}>>>]
  [ini_pp]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../../source/functions/MooseParsedFunction.html"}>>>
    symbol_names<<<{"description": "Symbols (excluding t,x,y,z) that are bound to the values provided by the corresponding items in the vals vector."}>>> = 'bulk p0 g    rho0'
    symbol_values<<<{"description": "Constant numeric values, postprocessor names, function names, and scalar variables corresponding to the symbols in symbol_names."}>>> = '2E3 0.0 1E-5 1E3'
    expression<<<{"description": "The user defined function."}>>> = '-bulk*log(exp(-p0/bulk)+g*rho0*z/bulk)'
  []
  [ini_xx]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../../source/functions/MooseParsedFunction.html"}>>>
    symbol_names<<<{"description": "Symbols (excluding t,x,y,z) that are bound to the values provided by the corresponding items in the vals vector."}>>> = 'bulk p0 g    rho0 biot'
    symbol_values<<<{"description": "Constant numeric values, postprocessor names, function names, and scalar variables corresponding to the symbols in symbol_names."}>>> = '2E3 0.0 1E-5 1E3  0.7'
    expression<<<{"description": "The user defined function."}>>> = '0.8*(2500*10E-6*z+biot*(-bulk*log(exp(-p0/bulk)+g*rho0*z/bulk)))'
  []
  [ini_zz]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../../source/functions/MooseParsedFunction.html"}>>>
    symbol_names<<<{"description": "Symbols (excluding t,x,y,z) that are bound to the values provided by the corresponding items in the vals vector."}>>> = 'bulk p0 g    rho0 biot'
    symbol_values<<<{"description": "Constant numeric values, postprocessor names, function names, and scalar variables corresponding to the symbols in symbol_names."}>>> = '2E3 0.0 1E-5 1E3  0.7'
    expression<<<{"description": "The user defined function."}>>> = '2500*10E-6*z+biot*(-bulk*log(exp(-p0/bulk)+g*rho0*z/bulk))'
  []
  [excav_sideways]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../../source/functions/MooseParsedFunction.html"}>>>
    symbol_names<<<{"description": "Symbols (excluding t,x,y,z) that are bound to the values provided by the corresponding items in the vals vector."}>>> = 'end_t ymin ymax  minval maxval slope'
    symbol_values<<<{"description": "Constant numeric values, postprocessor names, function names, and scalar variables corresponding to the symbols in symbol_names."}>>> = '0.5   0    1000.0 1E-9 1 60'
    # excavation face at ymin+(ymax-ymin)*min(t/end_t,1)
    # slope is the distance over which the modulus reduces from maxval to minval
    expression<<<{"description": "The user defined function."}>>> = 'if(y<ymin+(ymax-ymin)*min(t/end_t,1),minval,if(y<ymin+(ymax-ymin)*min(t/end_t,1)+slope,minval+(maxval-minval)*(y-(ymin+(ymax-ymin)*min(t/end_t,1)))/slope,maxval))'
  []
  [density_sideways]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../../source/functions/MooseParsedFunction.html"}>>>
    symbol_names<<<{"description": "Symbols (excluding t,x,y,z) that are bound to the values provided by the corresponding items in the vals vector."}>>> = 'end_t ymin ymax  minval maxval'
    symbol_values<<<{"description": "Constant numeric values, postprocessor names, function names, and scalar variables corresponding to the symbols in symbol_names."}>>> = '0.5   0    1000.0 0 2500'
    expression<<<{"description": "The user defined function."}>>> = 'if(y<ymin+(ymax-ymin)*min(t/end_t,1),minval,maxval)'
  []
  [roof_conductance]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../../source/functions/MooseParsedFunction.html"}>>>
    symbol_names<<<{"description": "Symbols (excluding t,x,y,z) that are bound to the values provided by the corresponding items in the vals vector."}>>> = 'end_t ymin ymax   maxval minval'
    symbol_values<<<{"description": "Constant numeric values, postprocessor names, function names, and scalar variables corresponding to the symbols in symbol_names."}>>> = '0.5   0    1000.0 1E7      0'
    expression<<<{"description": "The user defined function."}>>> = 'if(y<ymin+(ymax-ymin)*min(t/end_t,1),maxval,minval)'
  []
[]

[UserObjects<<<{"href": "../../syntax/UserObjects/index.html"}>>>]
  [dictator]
    type = PorousFlowDictator<<<{"description": "Holds information on the PorousFlow variable names", "href": "../../source/userobjects/PorousFlowDictator.html"}>>>
    porous_flow_vars<<<{"description": "List of primary variables that are used in the PorousFlow simulation.  Jacobian entries involving derivatives wrt these variables will be computed.  In single-phase models you will just have one (eg 'pressure'), in two-phase models you will have two (eg 'p_water p_gas', or 'p_water s_water'), etc."}>>> = 'porepressure disp_x disp_y disp_z'
    number_fluid_phases<<<{"description": "The number of fluid phases in the simulation"}>>> = 1
    number_fluid_components<<<{"description": "The number of fluid components in the simulation"}>>> = 1
  []
  [pc]
    type = PorousFlowCapillaryPressureVG<<<{"description": "van Genuchten capillary pressure", "href": "../../source/userobjects/PorousFlowCapillaryPressureVG.html"}>>>
    m<<<{"description": "van Genuchten exponent m. Must be between 0 and 1, and optimally should be set to >0.5"}>>> = 0.5
    alpha<<<{"description": "van Genuchten parameter alpha. Must be positive"}>>> = 1 # MPa^-1
  []

  [mc_coh_strong_harden]
    type = TensorMechanicsHardeningExponential<<<{"description": "Hardening is Exponential", "href": "../../source/userobjects/SolidMechanicsHardeningExponential.html"}>>>
    value_0<<<{"description": "The value of the parameter at internal_parameter = 0"}>>> = 1.99 # MPa
    value_residual<<<{"description": "The value of the parameter for internal_parameter = infinity.  Default = value_0, ie perfect plasticity"}>>> = 2.01 # MPa
    rate<<<{"description": "Let p = internal_parameter.  Then value = value_residual + (value_0 - value_residual)*exp(-rate*intnal_parameter)"}>>> = 1.0
  []
  [mc_fric]
    type = TensorMechanicsHardeningConstant<<<{"description": "No hardening - the parameter is independent of the internal parameter(s)", "href": "../../source/userobjects/SolidMechanicsHardeningConstant.html"}>>>
    value<<<{"description": "The value of the parameter for all internal parameter.  This is perfect plasticity - there is no hardening."}>>> = 0.61 # 35deg
  []
  [mc_dil]
    type = TensorMechanicsHardeningConstant<<<{"description": "No hardening - the parameter is independent of the internal parameter(s)", "href": "../../source/userobjects/SolidMechanicsHardeningConstant.html"}>>>
    value<<<{"description": "The value of the parameter for all internal parameter.  This is perfect plasticity - there is no hardening."}>>> = 0.15 # 8deg
  []

  [mc_tensile_str_strong_harden]
    type = TensorMechanicsHardeningExponential<<<{"description": "Hardening is Exponential", "href": "../../source/userobjects/SolidMechanicsHardeningExponential.html"}>>>
    value_0<<<{"description": "The value of the parameter at internal_parameter = 0"}>>> = 1.0 # MPa
    value_residual<<<{"description": "The value of the parameter for internal_parameter = infinity.  Default = value_0, ie perfect plasticity"}>>> = 1.0 # MPa
    rate<<<{"description": "Let p = internal_parameter.  Then value = value_residual + (value_0 - value_residual)*exp(-rate*intnal_parameter)"}>>> = 1.0
  []
  [mc_compressive_str]
    type = TensorMechanicsHardeningCubic<<<{"description": "Hardening is Cubic", "href": "../../source/userobjects/SolidMechanicsHardeningCubic.html"}>>>
    value_0<<<{"description": "The value of the parameter for all internal_parameter <= internal_0"}>>> = 100 # Large!
    value_residual<<<{"description": "The value of the parameter for internal_parameter >= internal_limit.  Default = value_0, ie perfect plasticity"}>>> = 100
    internal_limit<<<{"description": "The value of the internal_parameter when hardening ends.  This hardening forms a cubic between (internal_0, value_0) and (internal_limit, value_residual) that is smooth at internal_0 and internal_limit"}>>> = 0.1
  []

  [wp_coh_harden]
    type = TensorMechanicsHardeningCubic<<<{"description": "Hardening is Cubic", "href": "../../source/userobjects/SolidMechanicsHardeningCubic.html"}>>>
    value_0<<<{"description": "The value of the parameter for all internal_parameter <= internal_0"}>>> = 0.05
    value_residual<<<{"description": "The value of the parameter for internal_parameter >= internal_limit.  Default = value_0, ie perfect plasticity"}>>> = 0.05
    internal_limit<<<{"description": "The value of the internal_parameter when hardening ends.  This hardening forms a cubic between (internal_0, value_0) and (internal_limit, value_residual) that is smooth at internal_0 and internal_limit"}>>> = 10
  []
  [wp_tan_fric]
    type = TensorMechanicsHardeningConstant<<<{"description": "No hardening - the parameter is independent of the internal parameter(s)", "href": "../../source/userobjects/SolidMechanicsHardeningConstant.html"}>>>
    value<<<{"description": "The value of the parameter for all internal parameter.  This is perfect plasticity - there is no hardening."}>>> = 0.26 # 15deg
  []
  [wp_tan_dil]
    type = TensorMechanicsHardeningConstant<<<{"description": "No hardening - the parameter is independent of the internal parameter(s)", "href": "../../source/userobjects/SolidMechanicsHardeningConstant.html"}>>>
    value<<<{"description": "The value of the parameter for all internal parameter.  This is perfect plasticity - there is no hardening."}>>> = 0.18 # 10deg
  []

  [wp_tensile_str_harden]
    type = TensorMechanicsHardeningCubic<<<{"description": "Hardening is Cubic", "href": "../../source/userobjects/SolidMechanicsHardeningCubic.html"}>>>
    value_0<<<{"description": "The value of the parameter for all internal_parameter <= internal_0"}>>> = 0.05
    value_residual<<<{"description": "The value of the parameter for internal_parameter >= internal_limit.  Default = value_0, ie perfect plasticity"}>>> = 0.05
    internal_limit<<<{"description": "The value of the internal_parameter when hardening ends.  This hardening forms a cubic between (internal_0, value_0) and (internal_limit, value_residual) that is smooth at internal_0 and internal_limit"}>>> = 10
  []
  [wp_compressive_str_soften]
    type = TensorMechanicsHardeningCubic<<<{"description": "Hardening is Cubic", "href": "../../source/userobjects/SolidMechanicsHardeningCubic.html"}>>>
    value_0<<<{"description": "The value of the parameter for all internal_parameter <= internal_0"}>>> = 100
    value_residual<<<{"description": "The value of the parameter for internal_parameter >= internal_limit.  Default = value_0, ie perfect plasticity"}>>> = 1
    internal_limit<<<{"description": "The value of the internal_parameter when hardening ends.  This hardening forms a cubic between (internal_0, value_0) and (internal_limit, value_residual) that is smooth at internal_0 and internal_limit"}>>> = 1.0
  []
[]

[FluidProperties<<<{"href": "../../syntax/FluidProperties/index.html"}>>>]
  [simple_fluid]
    type = SimpleFluidProperties<<<{"description": "Fluid properties for a simple fluid with a constant bulk density", "href": "../../source/fluidproperties/SimpleFluidProperties.html"}>>>
    bulk_modulus<<<{"description": "Constant bulk modulus (Pa)"}>>> = 2E3
    density0<<<{"description": "Density at zero pressure and zero temperature"}>>> = 1000
    thermal_expansion<<<{"description": "Constant coefficient of thermal expansion (1/K)"}>>> = 0
    viscosity<<<{"description": "Constant dynamic viscosity (Pa.s)"}>>> = 3.5E-17
  []
[]
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

A van Genuchten capillary pressure relationship is used

  [pc]
    type = PorousFlowCapillaryPressureVG
    m = 0.5
    alpha = 1 # MPa^-1
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

A Corey relative permeability is used

  [relperm]
    type = PorousFlowRelativePermeabilityCorey
    n = 4
    s_res = 0.4
    sum_s_res = 0.4
    phase = 0
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

The fluid porepressure is fixed at the outer boundaries, and a PorousFlowPiecewiseLinearSink with a spatially and temporally varying flux_function is used to withdraw water from the rock into the goaf:

  [fix_porepressure]
    type = FunctionDirichletBC
    variable = porepressure
    boundary = 'ymin ymax xmax'
    function = ini_pp
  []
  [roof_porepressure]
    type = PorousFlowPiecewiseLinearSink
    variable = porepressure
    pt_vals = '-1E3 1E3'
    multipliers = '-1 1'
    fluid_phase = 0
    flux_function = roof_conductance
    boundary = roof
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

In multi-phase scenarios, such a simple representation of the goaf boundary condition is not valid.

Solid mechanics

Layered Cosserat solid mechanics is employed, meaning there are 3 translational and 2 rotational degrees of freedom. A quasi-static approximation is used, so the solid-mechanical Kernels are

  [cx_elastic]
    type = CosseratStressDivergenceTensors
    use_displaced_mesh = false
    variable = disp_x
    component = 0
  []
  [cy_elastic]
    type = CosseratStressDivergenceTensors
    use_displaced_mesh = false
    variable = disp_y
    component = 1
  []
  [cz_elastic]
    type = CosseratStressDivergenceTensors
    use_displaced_mesh = false
    variable = disp_z
    component = 2
  []
  [x_couple]
    type = StressDivergenceTensors
    use_displaced_mesh = false
    variable = wc_x
    displacements = 'wc_x wc_y wc_z'
    component = 0
    base_name = couple
  []
  [y_couple]
    type = StressDivergenceTensors
    use_displaced_mesh = false
    variable = wc_y
    displacements = 'wc_x wc_y wc_z'
    component = 1
    base_name = couple
  []
  [x_moment]
    type = MomentBalancing
    use_displaced_mesh = false
    variable = wc_x
    component = 0
  []
  [y_moment]
    type = MomentBalancing
    use_displaced_mesh = false
    variable = wc_y
    component = 1
  []
  [gravity]
    type = Gravity
    use_displaced_mesh = false
    variable = disp_z
    value = -10E-6 # remember this is in MPa
  []
  [poro_x]
    type = PorousFlowEffectiveStressCoupling
    use_displaced_mesh = false
    variable = disp_x
    component = 0
  []
  [poro_y]
    type = PorousFlowEffectiveStressCoupling
    use_displaced_mesh = false
    variable = disp_y
    component = 1
  []
  [poro_z]
    type = PorousFlowEffectiveStressCoupling
    use_displaced_mesh = false
    component = 2
    variable = disp_z
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

Quite a complicated elasto-plastic model is used and this accounts for the majority of nonlinear iterations of this model, as well as the relative slowness of computing the residual and Jacobian. The elasticity tensors (one for standard, one for Cosserat) are computed via:

  [elasticity_tensor_0]
    type = ComputeLayeredCosseratElasticityTensor
     block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    young = 8E3 # MPa
    poisson = 0.25
    layer_thickness = 1.0
    joint_normal_stiffness = 1E9 # huge
    joint_shear_stiffness = 1E3 # MPa
  []
  [elasticity_tensor_1]
    type = ComputeLayeredCosseratElasticityTensor
    block = 1
    young = 8E3 # MPa
    poisson = 0.25
    layer_thickness = 1.0
    joint_normal_stiffness = 1E9 # huge
    joint_shear_stiffness = 1E3 # MPa
    elasticity_tensor_prefactor = excav_sideways
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

where the excav_sideways Function simulates the excavation of coal (it is 1 ahead of the coal face and zero behind it). Small strain is used, and an insitu stress that increases with depth is assumed:

  [strain]
    type = ComputeCosseratIncrementalSmallStrain
    eigenstrain_names = ini_stress
  []
  [ini_stress]
    type = ComputeEigenstrainFromInitialStress
    eigenstrain_name = ini_stress
    initial_stress = 'ini_xx 0 0  0 ini_xx 0  0 0 ini_zz'
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

Capped Mohr-Coulomb plus weak-plane plasticity is used and the plastic models are cycled

  [stress_0]
    type = ComputeMultipleInelasticCosseratStress
     block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    inelastic_models = 'mc wp'
    cycle_models = true
    relative_tolerance = 2.0
    absolute_tolerance = 1E6
    max_iterations = 1
    tangent_operator = nonlinear
    perform_finite_strain_rotations = false
  []
  [stress_1]
    type = ComputeMultipleInelasticCosseratStress
    block = 1
    inelastic_models = ''
    relative_tolerance = 2.0
    absolute_tolerance = 1E6
    max_iterations = 1
    tangent_operator = nonlinear
    perform_finite_strain_rotations = false
  []
  [mc]
    type = CappedMohrCoulombCosseratStressUpdate
    warn_about_precision_loss = false
    host_youngs_modulus = 8E3
    host_poissons_ratio = 0.25
    base_name = mc
    tensile_strength = mc_tensile_str_strong_harden
    compressive_strength = mc_compressive_str
    cohesion = mc_coh_strong_harden
    friction_angle = mc_fric
    dilation_angle = mc_dil
    max_NR_iterations = 100000
    smoothing_tol = 0.1 # MPa  # Must be linked to cohesion
    yield_function_tol = 1E-9 # MPa.  this is essentially the lowest possible without lots of precision loss
    perfect_guess = true
    min_step_size = 1.0
  []
  [wp]
    type = CappedWeakPlaneCosseratStressUpdate
    warn_about_precision_loss = false
    base_name = wp
    cohesion = wp_coh_harden
    tan_friction_angle = wp_tan_fric
    tan_dilation_angle = wp_tan_dil
    tensile_strength = wp_tensile_str_harden
    compressive_strength = wp_compressive_str_soften
    max_NR_iterations = 10000
    tip_smoother = 0.05
    smoothing_tol = 0.05 # MPa  # Note, this must be tied to cohesion, otherwise get no possible return at cone apex
    yield_function_tol = 1E-11 # MPa.  this is essentially the lowest possible without lots of precision loss
    perfect_guess = true
    min_step_size = 1.0E-3
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

The plastic moduli are:

  [mc_coh_strong_harden]
    type = TensorMechanicsHardeningExponential
    value_0 = 1.99 # MPa
    value_residual = 2.01 # MPa
    rate = 1.0
  []
  [mc_fric]
    type = TensorMechanicsHardeningConstant
    value = 0.61 # 35deg
  []
  [mc_dil]
    type = TensorMechanicsHardeningConstant
    value = 0.15 # 8deg
  []

  [mc_tensile_str_strong_harden]
    type = TensorMechanicsHardeningExponential
    value_0 = 1.0 # MPa
    value_residual = 1.0 # MPa
    rate = 1.0
  []
  [mc_compressive_str]
    type = TensorMechanicsHardeningCubic
    value_0 = 100 # Large!
    value_residual = 100
    internal_limit = 0.1
  []

  [wp_coh_harden]
    type = TensorMechanicsHardeningCubic
    value_0 = 0.05
    value_residual = 0.05
    internal_limit = 10
  []
  [wp_tan_fric]
    type = TensorMechanicsHardeningConstant
    value = 0.26 # 15deg
  []
  [wp_tan_dil]
    type = TensorMechanicsHardeningConstant
    value = 0.18 # 10deg
  []

  [wp_tensile_str_harden]
    type = TensorMechanicsHardeningCubic
    value_0 = 0.05
    value_residual = 0.05
    internal_limit = 10
  []
  [wp_compressive_str_soften]
    type = TensorMechanicsHardeningCubic
    value_0 = 100
    value_residual = 1
    internal_limit = 1.0
  []
[]

[FluidProperties]
  [simple_fluid]
    type = SimpleFluidProperties
    bulk_modulus = 2E3
    density0 = 1000
    thermal_expansion = 0
    viscosity = 3.5E-17
  []
[]

[Materials]
  [temperature]
    type = PorousFlowTemperature
  []
  [eff_fluid_pressure]
    type = PorousFlowEffectiveFluidPressure
  []
  [vol_strain]
    type = PorousFlowVolumetricStrain
  []
  [ppss]
    type = PorousFlow1PhaseP
    porepressure = porepressure
    capillary_pressure = pc
  []
  [massfrac]
    type = PorousFlowMassFraction
  []
  [simple_fluid]
    type = PorousFlowSingleComponentFluid
    fp = simple_fluid
    phase = 0
  []
  [porosity_bulk]
    type = PorousFlowPorosity
    fluid = true
    mechanical = true
    block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    ensure_positive = true
    porosity_zero = 0.02
    solid_bulk = 5.3333E3
  []
  [porosity_excav]
    type = PorousFlowPorosityConst
    block = 1
    porosity = 1.0
  []
  [permeability_bulk]
    type = PorousFlowPermeabilityKozenyCarman
    block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    poroperm_function = kozeny_carman_phi0
    k0 = 1E-15
    phi0 = 0.02
    n = 2
    m = 2
  []
  [permeability_excav]
    type = PorousFlowPermeabilityConst
    block = 1
    permeability = '0 0 0   0 0 0   0 0 0'
  []
  [relperm]
    type = PorousFlowRelativePermeabilityCorey
    n = 4
    s_res = 0.4
    sum_s_res = 0.4
    phase = 0
  []

  [elasticity_tensor_0]
    type = ComputeLayeredCosseratElasticityTensor
     block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    young = 8E3 # MPa
    poisson = 0.25
    layer_thickness = 1.0
    joint_normal_stiffness = 1E9 # huge
    joint_shear_stiffness = 1E3 # MPa
  []
  [elasticity_tensor_1]
    type = ComputeLayeredCosseratElasticityTensor
    block = 1
    young = 8E3 # MPa
    poisson = 0.25
    layer_thickness = 1.0
    joint_normal_stiffness = 1E9 # huge
    joint_shear_stiffness = 1E3 # MPa
    elasticity_tensor_prefactor = excav_sideways
  []
  [strain]
    type = ComputeCosseratIncrementalSmallStrain
    eigenstrain_names = ini_stress
  []
  [ini_stress]
    type = ComputeEigenstrainFromInitialStress
    eigenstrain_name = ini_stress
    initial_stress = 'ini_xx 0 0  0 ini_xx 0  0 0 ini_zz'
  []

  [stress_0]
    type = ComputeMultipleInelasticCosseratStress
     block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    inelastic_models = 'mc wp'
    cycle_models = true
    relative_tolerance = 2.0
    absolute_tolerance = 1E6
    max_iterations = 1
    tangent_operator = nonlinear
    perform_finite_strain_rotations = false
  []
  [stress_1]
    type = ComputeMultipleInelasticCosseratStress
    block = 1
    inelastic_models = ''
    relative_tolerance = 2.0
    absolute_tolerance = 1E6
    max_iterations = 1
    tangent_operator = nonlinear
    perform_finite_strain_rotations = false
  []
  [mc]
    type = CappedMohrCoulombCosseratStressUpdate
    warn_about_precision_loss = false
    host_youngs_modulus = 8E3
    host_poissons_ratio = 0.25
    base_name = mc
    tensile_strength = mc_tensile_str_strong_harden
    compressive_strength = mc_compressive_str
    cohesion = mc_coh_strong_harden
    friction_angle = mc_fric
    dilation_angle = mc_dil
    max_NR_iterations = 100000
    smoothing_tol = 0.1 # MPa  # Must be linked to cohesion
    yield_function_tol = 1E-9 # MPa.  this is essentially the lowest possible without lots of precision loss
    perfect_guess = true
    min_step_size = 1.0
  []
  [wp]
    type = CappedWeakPlaneCosseratStressUpdate
    warn_about_precision_loss = false
    base_name = wp
    cohesion = wp_coh_harden
    tan_friction_angle = wp_tan_fric
    tan_dilation_angle = wp_tan_dil
    tensile_strength = wp_tensile_str_harden
    compressive_strength = wp_compressive_str_soften
    max_NR_iterations = 10000
    tip_smoother = 0.05
    smoothing_tol = 0.05 # MPa  # Note, this must be tied to cohesion, otherwise get no possible return at cone apex
    yield_function_tol = 1E-11 # MPa.  this is essentially the lowest possible without lots of precision loss
    perfect_guess = true
    min_step_size = 1.0E-3
  []

  [undrained_density_0]
    type = GenericConstantMaterial
     block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    prop_names = density
    prop_values = 2500
  []
  [undrained_density_1]
    type = GenericFunctionMaterial
    block = 1
    prop_names = density
    prop_values = density_sideways
  []
[]

[Preconditioning]
  [SMP]
    type = SMP
    full = true
  []
[]

[Postprocessors]
  [min_roof_disp]
    type = NodalExtremeValue
    boundary = roof
    value_type = min
    variable = disp_z
  []
  [min_roof_pp]
    type = NodalExtremeValue
    boundary = roof
    value_type = min
    variable = porepressure
  []
  [min_surface_disp]
    type = NodalExtremeValue
    boundary = zmax
    value_type = min
    variable = disp_z
  []
  [min_surface_pp]
    type = NodalExtremeValue
    boundary = zmax
    value_type = min
    variable = porepressure
  []
  [max_perm_zz]
    type = ElementExtremeValue
     block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    variable = perm_zz
  []
[]

[Executioner]
  type = Transient

  solve_type = 'NEWTON'

  petsc_options = '-snes_converged_reason'

  # best overall
  # petsc_options_iname = '-pc_type -pc_factor_mat_solver_package'
  # petsc_options_value = ' lu       mumps'

  # best if you do not have mumps:
  petsc_options_iname = '-pc_type -pc_factor_mat_solver_package'
  petsc_options_value = ' lu       superlu_dist'

  # best if you do not have mumps or superlu_dist:
  #petsc_options_iname = '-pc_type -pc_asm_overlap -sub_pc_type -ksp_type -ksp_gmres_restart'
  #petsc_options_value = ' asm      2              lu            gmres     200'

  # very basic:
  #petsc_options_iname = '-pc_type -ksp_type -ksp_gmres_restart'
  #petsc_options_value = ' bjacobi  gmres     200'

  line_search = bt

  nl_abs_tol = 1e-3
  nl_rel_tol = 1e-5

  l_max_its = 200
  nl_max_its = 30

  start_time = 0.0
  dt = 0.014706
  end_time = 0.014706 #0.5
[]

[Outputs]
  time_step_interval = 1
  print_linear_residuals = true
  exodus = true
  csv = true
  console = true
[]
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

Roller boundary conditions are prescribed at the boundaries. At the roof of the excavation, a StickyBC is employed to prevent the roof from collapsing further than 3m:

  [roof_bcs]
    type = StickyBC
    variable = disp_z
    min_value = -3.0
    boundary = roof
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

Coupling

Full coupling between the fluid and solid mechanics is evident in the Kernels. The PorousFlowDictator ensures all nonzero Jacobian entries are computed:

  [dictator]
    type = PorousFlowDictator
    porous_flow_vars = 'porepressure disp_x disp_y disp_z'
    number_fluid_phases = 1
    number_fluid_components = 1
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

Other aspects of the fluid-solid coupling are the porosity:

  [porosity_bulk]
    type = PorousFlowPorosity
    fluid = true
    mechanical = true
    block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    ensure_positive = true
    porosity_zero = 0.02
    solid_bulk = 5.3333E3
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

and the permeability:

  [permeability_bulk]
    type = PorousFlowPermeabilityKozenyCarman
    block = '2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
    poroperm_function = kozeny_carman_phi0
    k0 = 1E-15
    phi0 = 0.02
    n = 2
    m = 2
  []
(modules/porous_flow/examples/coal_mining/coarse_with_fluid.i)

Results

Despite being a very simple model with no interesting lithology that usually induces characteristic fracture and displacement patterns, the results display many interesting features.

Figure 3: The evolution of the destressed zone where the vertical stress has less magnitude than the initial vertical stress. The zone is colored by the magnitude of de-stressing. The black rectangle shows the coal that will be excavated.

Figure 4: The evolution of the zone where the vertical displacement is cm. The zone is colored by the magnitude of vertical displacement. The black rectangle shows the coal that will be excavated.

Figure 5: The evolution of the zone where the porepressure is reduced by more than MPa. The zone is colored by the magnitude of the porepressure reduction. The green arrows show the Darcy velocity. The black rectangle shows the coal that will be excavated.

Some of interesting features are:

  • Initially the roof holds up before suddenly collapsing at around 100m of excavation.

  • After this point, there is some periodicity in the plastic strains and vertical stresses, although this may be an artifact of the mesh rather than anything physical.

  • The minimum vertical displacement is actually m in the region where the sudden collapse occurs towards the start of the panel. The StickyBC are not sufficient to prevent this. Therefore, the results towards the panel's beginning shouldn't be treated too seriously. To avoid this, MOOSE's Constraint system, or the mining-specific features CSIRO's private MOOSE-based app, could be employed.

  • There is significant rock fracture, indicated by the Mohr-Coulomb plastic strains of greater than % in the immediate 10m of the roof.

  • Mohr-Coulomb shear failure is much more prevalent than Mohr-Coulomb tensile failure throughout the model.

  • Mohr-Coulomb shear failure also occurs in the unexcavated material close to the panel (the ribs and roadways).

  • Tensile opening of the joints occurs in large regions of the roof, indicated by weak-plane tensile plasticity of greater than %.

  • Shear failure of the joints occurs throughout all regions of the model above the goaf. It is greater than 1% in the immediate m of the roof.

  • The surrounding unexcavated material experiences large vertical loads, while there is an annular region on the outside and above the excavation that is de-stressed. The material above the goaf therefore experiences de-stressing and then recompaction.

  • Porosity and permeability enhancement typically occurs in regions of highest weak-plane failure. The permeability is increased by approximately a factor of 2 in the goaf region. This is actually a tiny enhancement compared to the expected value of around and is due to the Kozeny-Carman permeability relationship which is not really valid in this setting. If readers are interested in simulating realistic mining-induced permeability enhancements they should enquire about using CSIRO's private MOOSE-based app.

  • Mining-induced drawdown of the water porepressure at the ground surface starts to occur after around m (2 weeks) of excavation. In this model, the region above the panel rapidly becomes unsaturated, with saturation reaching approximately 80%, as water flows to the goaf region.

  • Most of the high Darcy fluid velocities occur around the periphery of the mining panel.

Results along the centre-line of the panel.

The figures below show results contoured on a vertical section along the centre-line of the panel, after excavation has completed. The excavation is shown as a black line.

Mohr-Coulomb shear plastic strain on a vertical section along the centre-line of the panel

Mohr-Coulomb tensile plastic strain on a vertical section along the centre-line of the panel

Weak-plane shear plastic strain on a vertical section along the centre-line of the panel

Weak-plane tensile plastic strain on a vertical section along the centre-line of the panel

Vertical permeability on a vertical section along the centre-line of the panel

Porepressure (color) and Darcy flow vectors on a vertical section along the centre-line of the panel

Results across the panel.

The figures below show results contoured on a vertical section across the half-panel that is modelled, after excavation has completed. The excavation is shown as a black line.

Mohr-Coulomb shear plastic strain on a vertical section across the panel

Mohr-Coulomb tensile plastic strain on a vertical section across the panel

Weak-plane shear plastic strain on a vertical section across the panel

Weak-plane tensile plastic strain on a vertical section across the panel

Vertical permeability on a vertical section across the panel

Porepressure (color) and Darcy flow vectors on a vertical section across the panel