Pressure-pulses in 1D

The PorousFlow fluid equation for single-phase flow through a fully saturated medium without gravity and without sources is just Darcy's equation (1) with notation described in the governing equations. Using , where is the fluid bulk modulus, Darcy's equation becomes (2) with (3) Here I've assumed the porosity and bulk modulus are constant in space and time.

Consider the one-dimensional case were the spatial dimension is the semi-infinite line . Suppose that initially the pressure is constant, so that (4) Then apply a fixed-pressure Dirichlet boundary condition at so that (5) The solution of the above differential equation is well known to be (6) where Erf is the error function.

A number of PorousFlow tests verify that this solution is produced with parameters shown in Table 1

Table 1: Parameter values used in the pressure-pulse tests

ParameterValue
length of 1D bar100 m
number of elements10
end time (for transient simulations)10000 s
number of time steps10
Fluid bulk modulus ()2 GPa
Fluid viscosity ()0.001 Pa.s
Permeability ()m
Porosity0.1
Initial pressure2 MPa
Applied pressure3 MPa

The tests include:

• Steady state 1-phase analysis to demonstrate that the steady-state of is achieved.

# Pressure pulse in 1D with 1 phase - steady
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
xmin = 0
xmax = 100
[]

[GlobalParams]
PorousFlowDictator = dictator
[]

[Variables]
[./pp]
initial_condition = 2E6
[../]
[]

[Kernels]
active = flux
[./mass0]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = pp
[../]
[./flux]
variable = pp
gravity = '0 0 0'
fluid_component = 0
[../]
[]

[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'pp'
number_fluid_phases = 1
number_fluid_components = 1
[../]
[./pc]
type = PorousFlowCapillaryPressureVG
m = 0.5
alpha = 1e-7
[../]
[]

[Modules]
[./FluidProperties]
[./simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 2e9
density0 = 1000
thermal_expansion = 0
viscosity = 1e-3
[../]
[../]
[]

[Materials]
[./temperature]
type = PorousFlowTemperature
[../]
[./ppss]
type = PorousFlow1PhaseP
porepressure = pp
capillary_pressure = pc
[../]
[./massfrac]
type = PorousFlowMassFraction
[../]
[./simple_fluid]
type = PorousFlowSingleComponentFluid
fp = simple_fluid
phase = 0
[../]
[./porosity]
type = PorousFlowPorosityConst
porosity = 0.1
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1E-15 0 0 0 1E-15 0 0 0 1E-15'
[../]
[./relperm]
type = PorousFlowRelativePermeabilityCorey
n = 0
phase = 0
[../]
[]

[BCs]
[./left]
type = DirichletBC
boundary = left
value = 3E6
variable = pp
[../]
[]

[Preconditioning]
[./andy]
type = SMP
full = true
petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it'
petsc_options_value = 'bcgs bjacobi 1E-15 1E-20 10000'
[../]
[]

[Executioner]
solve_type = Newton
[]

[Postprocessors]
[./p000]
type = PointValue
variable = pp
point = '0 0 0'
execute_on = 'initial timestep_end'
[../]
[./p010]
type = PointValue
variable = pp
point = '10 0 0'
execute_on = 'initial timestep_end'
[../]
[./p020]
type = PointValue
variable = pp
point = '20 0 0'
execute_on = 'initial timestep_end'
[../]
[./p030]
type = PointValue
variable = pp
point = '30 0 0'
execute_on = 'initial timestep_end'
[../]
[./p040]
type = PointValue
variable = pp
point = '40 0 0'
execute_on = 'initial timestep_end'
[../]
[./p050]
type = PointValue
variable = pp
point = '50 0 0'
execute_on = 'initial timestep_end'
[../]
[./p060]
type = PointValue
variable = pp
point = '60 0 0'
execute_on = 'initial timestep_end'
[../]
[./p070]
type = PointValue
variable = pp
point = '70 0 0'
execute_on = 'initial timestep_end'
[../]
[./p080]
type = PointValue
variable = pp
point = '80 0 0'
execute_on = 'initial timestep_end'
[../]
[./p090]
type = PointValue
variable = pp
point = '90 0 0'
execute_on = 'initial timestep_end'
[../]
[./p100]
type = PointValue
variable = pp
point = '100 0 0'
execute_on = 'initial timestep_end'
[../]
[]

[Outputs]
print_linear_residuals = false
csv = true
[]

• Transient 1-phase analysis.

# Pressure pulse in 1D with 1 phase - transient
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
xmin = 0
xmax = 100
[]

[GlobalParams]
PorousFlowDictator = dictator
[]

[Variables]
[./pp]
initial_condition = 2E6
[../]
[]

[Kernels]
[./mass0]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = pp
[../]
[./flux]
variable = pp
gravity = '0 0 0'
fluid_component = 0
[../]
[]

[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'pp'
number_fluid_phases = 1
number_fluid_components = 1
[../]
[./pc]
type = PorousFlowCapillaryPressureVG
m = 0.5
alpha = 1e-7
[../]
[]

[Modules]
[./FluidProperties]
[./simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 2e9
density0 = 1000
thermal_expansion = 0
viscosity = 1e-3
[../]
[../]
[]

[Materials]
[./temperature]
type = PorousFlowTemperature
[../]
[./ppss]
type = PorousFlow1PhaseP
porepressure = pp
capillary_pressure = pc
[../]
[./massfrac]
type = PorousFlowMassFraction
[../]
[./simple_fluid]
type = PorousFlowSingleComponentFluid
fp = simple_fluid
phase = 0
[../]
[./porosity]
type = PorousFlowPorosityConst
porosity = 0.1
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1E-15 0 0 0 1E-15 0 0 0 1E-15'
[../]
[./relperm]
type = PorousFlowRelativePermeabilityCorey
n = 0
phase = 0
[../]
[]

[BCs]
[./left]
type = DirichletBC
boundary = left
value = 3E6
variable = pp
[../]
[]

[Preconditioning]
[./andy]
type = SMP
full = true
petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it'
petsc_options_value = 'bcgs bjacobi 1E-15 1E-20 10000'
[../]
[]

[Executioner]
type = Transient
solve_type = Newton
dt = 1E3
end_time = 1E4
[]

[Postprocessors]
[./p000]
type = PointValue
variable = pp
point = '0 0 0'
execute_on = 'initial timestep_end'
[../]
[./p010]
type = PointValue
variable = pp
point = '10 0 0'
execute_on = 'initial timestep_end'
[../]
[./p020]
type = PointValue
variable = pp
point = '20 0 0'
execute_on = 'initial timestep_end'
[../]
[./p030]
type = PointValue
variable = pp
point = '30 0 0'
execute_on = 'initial timestep_end'
[../]
[./p040]
type = PointValue
variable = pp
point = '40 0 0'
execute_on = 'initial timestep_end'
[../]
[./p050]
type = PointValue
variable = pp
point = '50 0 0'
execute_on = 'initial timestep_end'
[../]
[./p060]
type = PointValue
variable = pp
point = '60 0 0'
execute_on = 'initial timestep_end'
[../]
[./p070]
type = PointValue
variable = pp
point = '70 0 0'
execute_on = 'initial timestep_end'
[../]
[./p080]
type = PointValue
variable = pp
point = '80 0 0'
execute_on = 'initial timestep_end'
[../]
[./p090]
type = PointValue
variable = pp
point = '90 0 0'
execute_on = 'initial timestep_end'
[../]
[./p100]
type = PointValue
variable = pp
point = '100 0 0'
execute_on = 'initial timestep_end'
[../]
[]

[Outputs]
file_base = pressure_pulse_1d
print_linear_residuals = false
csv = true
[]

(modules/porous_flow/test/tests/pressure_pulse/pressure_pulse_1d.i)
• Transient 1-phase, 3 component analysis to check that the components diffuse at the same rate.

# Pressure pulse in 1D with 1 phase but 3 components (viscosity, relperm, etc are independent of mass-fractions) - transient
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
xmin = 0
xmax = 100
[]

[GlobalParams]
PorousFlowDictator = dictator
[]

[Variables]
[./pp]
initial_condition = 2E6
[../]
[./massfrac0]
initial_condition = 0.1
[../]
[./massfrac1]
initial_condition = 0.3
[../]
[]

[Kernels]
[./mass0]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = pp
[../]
[./flux0]
variable = pp
gravity = '0 0 0'
fluid_component = 0
[../]
[./mass1]
type = PorousFlowMassTimeDerivative
fluid_component = 1
variable = massfrac0
[../]
[./flux1]
variable = massfrac0
gravity = '0 0 0'
fluid_component = 1
[../]
[./mass2]
type = PorousFlowMassTimeDerivative
fluid_component = 2
variable = massfrac1
[../]
[./flux2]
variable = massfrac1
gravity = '0 0 0'
fluid_component = 2
[../]
[]

[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'pp massfrac0 massfrac1'
number_fluid_phases = 1
number_fluid_components = 3
[../]
[./pc]
type = PorousFlowCapillaryPressureVG
m = 0.5
alpha = 1e-7
[../]
[]

[Modules]
[./FluidProperties]
[./simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 2e9
density0 = 1000
thermal_expansion = 0
viscosity = 1e-3
[../]
[../]
[]

[Materials]
[./temperature]
type = PorousFlowTemperature
[../]
[./ppss]
type = PorousFlow1PhaseP
porepressure = pp
capillary_pressure = pc
[../]
[./massfrac]
type = PorousFlowMassFraction
mass_fraction_vars = 'massfrac0 massfrac1'
[../]
[./simple_fluid]
type = PorousFlowSingleComponentFluid
fp = simple_fluid
phase = 0
[../]
[./porosity]
type = PorousFlowPorosityConst
porosity = 0.1
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1E-15 0 0 0 1E-15 0 0 0 1E-15'
[../]
[./relperm]
type = PorousFlowRelativePermeabilityCorey
n = 0
phase = 0
[../]
[]

[BCs]
[./left]
type = PresetBC
boundary = left
value = 3E6
variable = pp
[../]
[]

[Preconditioning]
[./andy]
type = SMP
full = true
petsc_options = '-snes_converged_reason -ksp_diagonal_scale -ksp_diagonal_scale_fix -ksp_gmres_modifiedgramschmidt -snes_linesearch_monitor'
petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap -snes_atol -snes_rtol -snes_max_it -ksp_rtol -ksp_atol'
petsc_options_value = 'gmres      asm      lu           NONZERO                   2               1E-7 1E-10 20 1E-10 1E-100'
[../]
[]

[Executioner]
type = Transient
solve_type = Newton
dt = 1E3
end_time = 1E4
[]

[Postprocessors]
[./p000]
type = PointValue
variable = pp
point = '0 0 0'
execute_on = 'initial timestep_end'
[../]
[./p010]
type = PointValue
variable = pp
point = '10 0 0'
execute_on = 'initial timestep_end'
[../]
[./p020]
type = PointValue
variable = pp
point = '20 0 0'
execute_on = 'initial timestep_end'
[../]
[./p030]
type = PointValue
variable = pp
point = '30 0 0'
execute_on = 'initial timestep_end'
[../]
[./p040]
type = PointValue
variable = pp
point = '40 0 0'
execute_on = 'initial timestep_end'
[../]
[./p050]
type = PointValue
variable = pp
point = '50 0 0'
execute_on = 'initial timestep_end'
[../]
[./p060]
type = PointValue
variable = pp
point = '60 0 0'
execute_on = 'initial timestep_end'
[../]
[./p070]
type = PointValue
variable = pp
point = '70 0 0'
execute_on = 'initial timestep_end'
[../]
[./p080]
type = PointValue
variable = pp
point = '80 0 0'
execute_on = 'initial timestep_end'
[../]
[./p090]
type = PointValue
variable = pp
point = '90 0 0'
execute_on = 'initial timestep_end'
[../]
[./p100]
type = PointValue
variable = pp
point = '100 0 0'
execute_on = 'initial timestep_end'
[../]
[./mf_0_010]
type = PointValue
variable = massfrac0
point = '10 0 0'
execute_on = 'timestep_end'
[../]
[./mf_1_010]
type = PointValue
variable = massfrac1
point = '10 0 0'
execute_on = 'timestep_end'
[../]
[]

[Outputs]
file_base = pressure_pulse_1d_3comp
print_linear_residuals = true
exodus = true
csv = true
[]

(modules/porous_flow/test/tests/pressure_pulse/pressure_pulse_1d_3comp.i)
• Transient 2-phase analysis, with the "water" state fully saturated.

# Pressure pulse in 1D with 2 phases (with one having zero saturation), 2components - transient
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
xmin = 0
xmax = 100
[]

[GlobalParams]
PorousFlowDictator = dictator
[]

[Variables]
[./ppwater]
initial_condition = 2E6
[../]
[./ppgas]
initial_condition = 2E6
[../]
[]

[AuxVariables]
[./massfrac_ph0_sp0]
initial_condition = 1
[../]
[./massfrac_ph1_sp0]
initial_condition = 0
[../]
[]

[Kernels]
[./mass0]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = ppwater
[../]
[./flux0]
variable = ppwater
gravity = '0 0 0'
fluid_component = 0
[../]
[./mass1]
type = PorousFlowMassTimeDerivative
fluid_component = 1
variable = ppgas
[../]
[./flux1]
variable = ppgas
gravity = '0 0 0'
fluid_component = 1
[../]
[]

[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'ppwater ppgas'
number_fluid_phases = 2
number_fluid_components = 2
[../]
[./pc]
type = PorousFlowCapillaryPressureVG
m = 0.5
alpha = 1
[../]
[]

[Modules]
[./FluidProperties]
[./simple_fluid0]
type = SimpleFluidProperties
bulk_modulus = 2e9
density0 = 1000
thermal_expansion = 0
viscosity = 1e-3
[../]
[./simple_fluid1]
type = SimpleFluidProperties
bulk_modulus = 2e6
density0 = 1
thermal_expansion = 0
viscosity = 1e-5
[../]
[../]
[]

[Materials]
[./temperature]
type = PorousFlowTemperature
[../]
[./ppss]
type = PorousFlow2PhasePP
phase0_porepressure = ppwater
phase1_porepressure = ppgas
capillary_pressure = pc
[../]
[./massfrac]
type = PorousFlowMassFraction
mass_fraction_vars = 'massfrac_ph0_sp0 massfrac_ph1_sp0'
[../]
[./simple_fluid0]
type = PorousFlowSingleComponentFluid
fp = simple_fluid0
phase = 0
[../]
[./simple_fluid1]
type = PorousFlowSingleComponentFluid
fp = simple_fluid1
phase = 1
[../]
[./porosity]
type = PorousFlowPorosityConst
porosity = 0.1
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1E-15 0 0 0 1E-15 0 0 0 1E-15'
[../]
[./relperm_water]
type = PorousFlowRelativePermeabilityCorey
n = 1
phase = 0
[../]
[./relperm_gas]
type = PorousFlowRelativePermeabilityCorey
n = 1
phase = 1
[../]
[]

[BCs]
[./leftwater]
type = DirichletBC
boundary = left
value = 3E6
variable = ppwater
[../]
[./leftgas]
type = DirichletBC
boundary = left
value = 3E6
variable = ppgas
[../]
[]

[Preconditioning]
[./andy]
type = SMP
full = true
petsc_options = '-snes_converged_reason -ksp_diagonal_scale -ksp_diagonal_scale_fix -ksp_gmres_modifiedgramschmidt -snes_linesearch_monitor'
petsc_options_iname = '-ksp_type -pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap -snes_atol -snes_rtol -snes_max_it'
petsc_options_value = 'gmres      asm      lu           NONZERO                   2               1E-15       1E-20 20'
[../]
[]

[Executioner]
type = Transient
solve_type = Newton
dt = 1E3
end_time = 1E4
[]

[Postprocessors]
[./p000]
type = PointValue
variable = ppwater
point = '0 0 0'
execute_on = 'initial timestep_end'
[../]
[./p010]
type = PointValue
variable = ppwater
point = '10 0 0'
execute_on = 'initial timestep_end'
[../]
[./p020]
type = PointValue
variable = ppwater
point = '20 0 0'
execute_on = 'initial timestep_end'
[../]
[./p030]
type = PointValue
variable = ppwater
point = '30 0 0'
execute_on = 'initial timestep_end'
[../]
[./p040]
type = PointValue
variable = ppwater
point = '40 0 0'
execute_on = 'initial timestep_end'
[../]
[./p050]
type = PointValue
variable = ppwater
point = '50 0 0'
execute_on = 'initial timestep_end'
[../]
[./p060]
type = PointValue
variable = ppwater
point = '60 0 0'
execute_on = 'initial timestep_end'
[../]
[./p070]
type = PointValue
variable = ppwater
point = '70 0 0'
execute_on = 'initial timestep_end'
[../]
[./p080]
type = PointValue
variable = ppwater
point = '80 0 0'
execute_on = 'initial timestep_end'
[../]
[./p090]
type = PointValue
variable = ppwater
point = '90 0 0'
execute_on = 'initial timestep_end'
[../]
[./p100]
type = PointValue
variable = ppwater
point = '100 0 0'
execute_on = 'initial timestep_end'
[../]
[]

[Outputs]
file_base = pressure_pulse_1d_2phase
print_linear_residuals = false
csv = true
[]

(modules/porous_flow/test/tests/pressure_pulse/pressure_pulse_1d_2phase.i)
• Transient 2-phase using the "PS" formulation

• 2-phase using the "PS" formulation and Kuzmin-Turek stabilisation

• 2 phase using the PS formulation and a van-Genuchten capillary pressure

• 2 phase using the PS formulation and a van-Genuchten capillary pressure with a logarithmic extension;

• 1 phase when the primary variable is

• 1 phase using the fully-saturated version of PorousFlow

• 1 phase with 3 fluid components using the fully-saturated version of PorousFlow.

An example verification is shown in Figure 1.

Figure 1: Comparison between the MOOSE result (in dots), and the exact analytic expression given by Eq. (6). The agreement increases for greater spatial resolution and smaller timesteps. Both the multi-component single-phase simulation (using the fully-saturated non-upwinding Kernels, or the partially-saturated full-upwinding Kernels, or the log(mass-density) primary variable) and the 2-phase fully-water-saturated simulation give identical results for the water porepressure.