It is also fairly straightforward to swap from full-upwinding (or no stabilization) to KT stabilization. Only two changes are needed in the input file.
Kernels
Instead of PorousFlowAdvectiveFlux or PorousFlowHeatAdvection or another type of PorousFlow Kernel, the PorousFlowFluxLimitedTVDAdvection Kernel must be used. For instance, a full-upwind simulation's Kernels are:
[Kernels]
[./mass_dot]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = pp
[../]
[./advection]
type = PorousFlowAdvectiveFlux
fluid_component = 0
variable = pp
[../]
[./energy_dot]
type = PorousFlowEnergyTimeDerivative
variable = temp
[../]
[./heat_advection]
type = PorousFlowHeatAdvection
variable = temp
[../]
(modules/porous_flow/test/tests/heat_advection/heat_advection_1d.i)/opt/civet/build_0/moose/modules/porous_flow/test/tests/heat_advection/heat_advection_1d.i
# 1phase, heat advecting with a moving fluid
[Mesh]
type = GeneratedMesh
dim = 1
nx = 50
xmin = 0
xmax = 1
[]
[GlobalParams]
PorousFlowDictator = dictator
gravity = '0 0 0'
[]
[Variables]
[./temp]
initial_condition = 200
[../]
[./pp]
[../]
[]
[ICs]
[./pp]
type = FunctionIC
variable = pp
function = '1-x'
[../]
[]
[BCs]
[./pp0]
type = DirichletBC
variable = pp
boundary = left
value = 1
[../]
[./pp1]
type = DirichletBC
variable = pp
boundary = right
value = 0
[../]
[./spit_heat]
type = DirichletBC
variable = temp
boundary = left
value = 300
[../]
[./suck_heat]
type = DirichletBC
variable = temp
boundary = right
value = 200
[../]
[]
[Kernels]
[./mass_dot]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = pp
[../]
[./advection]
type = PorousFlowAdvectiveFlux
fluid_component = 0
variable = pp
[../]
[./energy_dot]
type = PorousFlowEnergyTimeDerivative
variable = temp
[../]
[./heat_advection]
type = PorousFlowHeatAdvection
variable = temp
[../]
[]
[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'temp pp'
number_fluid_phases = 1
number_fluid_components = 1
[../]
[./pc]
type = PorousFlowCapillaryPressureVG
m = 0.6
alpha = 1.3
[../]
[]
[Modules]
[./FluidProperties]
[./simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 100
density0 = 1000
viscosity = 4.4
thermal_expansion = 0
cv = 2
[../]
[../]
[]
[Materials]
[./temperature]
type = PorousFlowTemperature
temperature = temp
[../]
[./porosity]
type = PorousFlowPorosityConst
porosity = 0.2
[../]
[./rock_heat]
type = PorousFlowMatrixInternalEnergy
specific_heat_capacity = 1.0
density = 125
[../]
[./simple_fluid]
type = PorousFlowSingleComponentFluid
fp = simple_fluid
phase = 0
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1.1 0 0 0 2 0 0 0 3'
[../]
[./relperm]
type = PorousFlowRelativePermeabilityCorey
n = 2
phase = 0
[../]
[./massfrac]
type = PorousFlowMassFraction
[../]
[./PS]
type = PorousFlow1PhaseP
porepressure = pp
capillary_pressure = pc
[../]
[]
[Preconditioning]
[./andy]
type = SMP
full = true
petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it'
petsc_options_value = 'gmres bjacobi 1E-15 1E-10 10000'
[../]
[]
[Executioner]
type = Transient
solve_type = Newton
dt = 0.01
end_time = 0.6
[]
[VectorPostprocessors]
[./T]
type = LineValueSampler
start_point = '0 0 0'
end_point = '1 0 0'
num_points = 51
sort_by = x
variable = temp
[../]
[]
[Outputs]
[./csv]
type = CSV
sync_times = '0.1 0.6'
sync_only = true
[../]
[]
while an identical simulation using KT stabilization has Kernels:
[Kernels]
[./mass_dot]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = pp
[../]
[./fluid_advection]
type = PorousFlowFluxLimitedTVDAdvection
variable = pp
advective_flux_calculator = fluid_advective_flux
[../]
[./energy_dot]
type = PorousFlowEnergyTimeDerivative
variable = temp
[../]
[./heat_advection]
type = PorousFlowFluxLimitedTVDAdvection
variable = temp
advective_flux_calculator = heat_advective_flux
[../]
(modules/porous_flow/test/tests/heat_advection/heat_advection_1d_KT.i)/opt/civet/build_0/moose/modules/porous_flow/test/tests/heat_advection/heat_advection_1d_KT.i
# 1phase, heat advecting with a moving fluid
# Using the Kuzmin-Turek stabilization scheme
[Mesh]
type = GeneratedMesh
dim = 1
nx = 50
xmin = 0
xmax = 1
[]
[GlobalParams]
PorousFlowDictator = dictator
gravity = '0 0 0'
[]
[Variables]
[./temp]
initial_condition = 200
[../]
[./pp]
[../]
[]
[ICs]
[./pp]
type = FunctionIC
variable = pp
function = '1-x'
[../]
[]
[BCs]
[./pp0]
type = DirichletBC
variable = pp
boundary = left
value = 1
[../]
[./pp1]
type = DirichletBC
variable = pp
boundary = right
value = 0
[../]
[./spit_heat]
type = DirichletBC
variable = temp
boundary = left
value = 300
[../]
[./suck_heat]
type = DirichletBC
variable = temp
boundary = right
value = 200
[../]
[]
[Kernels]
[./mass_dot]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = pp
[../]
[./fluid_advection]
type = PorousFlowFluxLimitedTVDAdvection
variable = pp
advective_flux_calculator = fluid_advective_flux
[../]
[./energy_dot]
type = PorousFlowEnergyTimeDerivative
variable = temp
[../]
[./heat_advection]
type = PorousFlowFluxLimitedTVDAdvection
variable = temp
advective_flux_calculator = heat_advective_flux
[../]
[]
[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'temp pp'
number_fluid_phases = 1
number_fluid_components = 1
[../]
[./pc]
type = PorousFlowCapillaryPressureVG
m = 0.6
alpha = 1.3
[../]
[./fluid_advective_flux]
type = PorousFlowAdvectiveFluxCalculatorSaturated
flux_limiter_type = superbee
[../]
[./heat_advective_flux]
type = PorousFlowAdvectiveFluxCalculatorSaturatedHeat
flux_limiter_type = superbee
[../]
[]
[Modules]
[./FluidProperties]
[./simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 100
density0 = 1000
viscosity = 4.4
thermal_expansion = 0
cv = 2
[../]
[../]
[]
[Materials]
[./temperature]
type = PorousFlowTemperature
temperature = temp
[../]
[./porosity]
type = PorousFlowPorosityConst
porosity = 0.2
[../]
[./rock_heat]
type = PorousFlowMatrixInternalEnergy
specific_heat_capacity = 1.0
density = 125
[../]
[./simple_fluid]
type = PorousFlowSingleComponentFluid
fp = simple_fluid
phase = 0
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1.1 0 0 0 2 0 0 0 3'
[../]
[./relperm]
type = PorousFlowRelativePermeabilityCorey
n = 2
phase = 0
[../]
[./massfrac]
type = PorousFlowMassFraction
[../]
[./PS]
type = PorousFlow1PhaseP
porepressure = pp
capillary_pressure = pc
[../]
[]
[Preconditioning]
[./andy]
type = SMP
full = true
petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it'
petsc_options_value = 'gmres bjacobi 1E-15 1E-10 10000'
[../]
[]
[Executioner]
type = Transient
solve_type = Newton
dt = 0.01
end_time = 0.6
[]
[VectorPostprocessors]
[./T]
type = LineValueSampler
start_point = '0 0 0'
end_point = '1 0 0'
num_points = 51
sort_by = x
variable = temp
[../]
[]
[Outputs]
file_base = heat_advection_1d_KT
[./csv]
type = CSV
sync_times = '0.1 0.6'
sync_only = true
[../]
[]
Notice that the PorousFlowFluxLimitedTVDAdvection
Kernels require an advective_flux_calculator
input. This is a UserObject, which is the subject of the next section.
UserObjects
The set of PorousFlow advective flux calculator UserObjects compute the Residual and Jacobian entries that are used by the PorousFlowFluxLimitedTVDAdvection Kernels. The reason that these entries are computed by UserObjects instead of Kernels is that the KT scheme requires information about porepressures, etc, that are 2 nodes away from the current node. This information gets assembled and processed to determine upwinding directions and suitable stabilization approaches before the residual and Jacobian are computed. The process is explained in the worked example of KT stabilization page. The upshot is that a UserObject must be employed instead of the usual MOOSE Kernel-only approach.
Table 1: Available types of PorousFlow advective flux UserObjects
Equation | UserObject | Use case |
---|
| PorousFlowAdvectiveFluxCalculatorSaturated | 1-phase, 1-component, fully-saturated |
| PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent | 1-phase, multi-component, fully-saturated |
| PorousFlowAdvectiveFluxCalculatorUnsaturated | 1-phase, 1-component, unsaturated |
| PorousFlowAdvectiveFluxCalculatorUnsaturated | multi-phase, multi-component, immiscible |
| PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent | multi-phase, multi-component |
| PorousFlowAdvectiveFluxCalculatorSaturatedHeat | heat, 1-phase |
| PorousFlowAdvectiveFluxCalculatorUnsaturatedHeat | heat, multi-phase |
The notation is detailed in the nomenclature: briefly, a subscript denotes a phase, a superscript denotes a fluid component, is a fluid density, a fluid viscosity, the permeability tensor, a fluid porepressure, the acceleration of gravity, a mass fraction, a relative permeability, and an enthalpy.
Which UserObjects you need depends on your simulation. For example, in the case of a single-phase, single-component, fully-saturated anisothermal simulation we need two UserObjects: one for the advection of the fluid, and one for the advection of the heat.
[./fluid_advective_flux]
type = PorousFlowAdvectiveFluxCalculatorSaturated
flux_limiter_type = superbee
[../]
[./heat_advective_flux]
type = PorousFlowAdvectiveFluxCalculatorSaturatedHeat
flux_limiter_type = superbee
[../]
(modules/porous_flow/test/tests/heat_advection/heat_advection_1d_KT.i)/opt/civet/build_0/moose/modules/porous_flow/test/tests/heat_advection/heat_advection_1d_KT.i
# 1phase, heat advecting with a moving fluid
# Using the Kuzmin-Turek stabilization scheme
[Mesh]
type = GeneratedMesh
dim = 1
nx = 50
xmin = 0
xmax = 1
[]
[GlobalParams]
PorousFlowDictator = dictator
gravity = '0 0 0'
[]
[Variables]
[./temp]
initial_condition = 200
[../]
[./pp]
[../]
[]
[ICs]
[./pp]
type = FunctionIC
variable = pp
function = '1-x'
[../]
[]
[BCs]
[./pp0]
type = DirichletBC
variable = pp
boundary = left
value = 1
[../]
[./pp1]
type = DirichletBC
variable = pp
boundary = right
value = 0
[../]
[./spit_heat]
type = DirichletBC
variable = temp
boundary = left
value = 300
[../]
[./suck_heat]
type = DirichletBC
variable = temp
boundary = right
value = 200
[../]
[]
[Kernels]
[./mass_dot]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = pp
[../]
[./fluid_advection]
type = PorousFlowFluxLimitedTVDAdvection
variable = pp
advective_flux_calculator = fluid_advective_flux
[../]
[./energy_dot]
type = PorousFlowEnergyTimeDerivative
variable = temp
[../]
[./heat_advection]
type = PorousFlowFluxLimitedTVDAdvection
variable = temp
advective_flux_calculator = heat_advective_flux
[../]
[]
[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'temp pp'
number_fluid_phases = 1
number_fluid_components = 1
[../]
[./pc]
type = PorousFlowCapillaryPressureVG
m = 0.6
alpha = 1.3
[../]
[./fluid_advective_flux]
type = PorousFlowAdvectiveFluxCalculatorSaturated
flux_limiter_type = superbee
[../]
[./heat_advective_flux]
type = PorousFlowAdvectiveFluxCalculatorSaturatedHeat
flux_limiter_type = superbee
[../]
[]
[Modules]
[./FluidProperties]
[./simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 100
density0 = 1000
viscosity = 4.4
thermal_expansion = 0
cv = 2
[../]
[../]
[]
[Materials]
[./temperature]
type = PorousFlowTemperature
temperature = temp
[../]
[./porosity]
type = PorousFlowPorosityConst
porosity = 0.2
[../]
[./rock_heat]
type = PorousFlowMatrixInternalEnergy
specific_heat_capacity = 1.0
density = 125
[../]
[./simple_fluid]
type = PorousFlowSingleComponentFluid
fp = simple_fluid
phase = 0
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1.1 0 0 0 2 0 0 0 3'
[../]
[./relperm]
type = PorousFlowRelativePermeabilityCorey
n = 2
phase = 0
[../]
[./massfrac]
type = PorousFlowMassFraction
[../]
[./PS]
type = PorousFlow1PhaseP
porepressure = pp
capillary_pressure = pc
[../]
[]
[Preconditioning]
[./andy]
type = SMP
full = true
petsc_options_iname = '-ksp_type -pc_type -snes_atol -snes_rtol -snes_max_it'
petsc_options_value = 'gmres bjacobi 1E-15 1E-10 10000'
[../]
[]
[Executioner]
type = Transient
solve_type = Newton
dt = 0.01
end_time = 0.6
[]
[VectorPostprocessors]
[./T]
type = LineValueSampler
start_point = '0 0 0'
end_point = '1 0 0'
num_points = 51
sort_by = x
variable = temp
[../]
[]
[Outputs]
file_base = heat_advection_1d_KT
[./csv]
type = CSV
sync_times = '0.1 0.6'
sync_only = true
[../]
[]
Clicking on the links in the above table will provide you with more examples. For instance the following set of Kernels and UserObjects illustrates the case of a single tracer in a fully-saturated single-phase fluid:
[Kernels]
[./mass0]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = tracer
[../]
[./flux0]
type = PorousFlowFluxLimitedTVDAdvection
variable = tracer
advective_flux_calculator = advective_flux_calculator_0
[../]
[./mass1]
type = PorousFlowMassTimeDerivative
fluid_component = 1
variable = porepressure
[../]
[./flux1]
type = PorousFlowFluxLimitedTVDAdvection
variable = porepressure
advective_flux_calculator = advective_flux_calculator_1
[../]
[]
(modules/porous_flow/test/tests/flux_limited_TVD_pflow/pffltvd_1D.i)/opt/civet/build_0/moose/modules/porous_flow/test/tests/flux_limited_TVD_pflow/pffltvd_1D.i
# Using flux-limited TVD advection ala Kuzmin and Turek, mploying PorousFlow Kernels and UserObjects, with superbee flux-limiter
# 1D version
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
xmin = 0
xmax = 1
[]
[GlobalParams]
PorousFlowDictator = dictator
gravity = '0 0 0'
[]
[Variables]
[./porepressure]
[../]
[./tracer]
[../]
[]
[ICs]
[./porepressure]
type = FunctionIC
variable = porepressure
function = '1 - x'
[../]
[./tracer]
type = FunctionIC
variable = tracer
function = 'if(x<0.1,0,if(x>0.3,0,1))'
[../]
[]
[Kernels]
[./mass0]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = tracer
[../]
[./flux0]
type = PorousFlowFluxLimitedTVDAdvection
variable = tracer
advective_flux_calculator = advective_flux_calculator_0
[../]
[./mass1]
type = PorousFlowMassTimeDerivative
fluid_component = 1
variable = porepressure
[../]
[./flux1]
type = PorousFlowFluxLimitedTVDAdvection
variable = porepressure
advective_flux_calculator = advective_flux_calculator_1
[../]
[]
[BCs]
[./constant_injection_porepressure]
type = DirichletBC
variable = porepressure
value = 1
boundary = left
[../]
[./no_tracer_on_left]
type = DirichletBC
variable = tracer
value = 0
boundary = left
[../]
[./remove_component_1]
type = PorousFlowPiecewiseLinearSink
variable = porepressure
boundary = right
fluid_phase = 0
pt_vals = '0 1E3'
multipliers = '0 1E3'
mass_fraction_component = 1
use_mobility = true
flux_function = 1E3
[../]
[./remove_component_0]
type = PorousFlowPiecewiseLinearSink
variable = tracer
boundary = right
fluid_phase = 0
pt_vals = '0 1E3'
multipliers = '0 1E3'
mass_fraction_component = 0
use_mobility = true
flux_function = 1E3
[../]
[]
[Modules]
[./FluidProperties]
[./the_simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 2E9
thermal_expansion = 0
viscosity = 1.0
density0 = 1000.0
[../]
[../]
[]
[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'porepressure tracer'
number_fluid_phases = 1
number_fluid_components = 2
[../]
[./pc]
type = PorousFlowCapillaryPressureConst
[../]
[./advective_flux_calculator_0]
type = PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent
flux_limiter_type = superbee
fluid_component = 0
[../]
[./advective_flux_calculator_1]
type = PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent
flux_limiter_type = superbee
fluid_component = 1
[../]
[]
[Materials]
[./temperature]
type = PorousFlowTemperature
[../]
[./ppss]
type = PorousFlow1PhaseP
porepressure = porepressure
capillary_pressure = pc
[../]
[./massfrac]
type = PorousFlowMassFraction
mass_fraction_vars = tracer
[../]
[./simple_fluid]
type = PorousFlowSingleComponentFluid
fp = the_simple_fluid
phase = 0
[../]
[./relperm]
type = PorousFlowRelativePermeabilityConst
phase = 0
[../]
[./porosity]
type = PorousFlowPorosity
porosity_zero = 0.1
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1E-2 0 0 0 1E-2 0 0 0 1E-2'
[../]
[]
[Preconditioning]
active = basic
[./basic]
type = SMP
full = true
petsc_options = '-ksp_diagonal_scale -ksp_diagonal_scale_fix'
petsc_options_iname = '-pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap'
petsc_options_value = ' asm lu NONZERO 2'
[../]
[./preferred_but_might_not_be_installed]
type = SMP
full = true
petsc_options_iname = '-pc_type -pc_factor_mat_solver_package'
petsc_options_value = ' lu mumps'
[../]
[]
[VectorPostprocessors]
[./tracer]
type = LineValueSampler
start_point = '0 0 0'
end_point = '1 0 0'
num_points = 11
sort_by = x
variable = tracer
[../]
[]
[Executioner]
type = Transient
solve_type = Newton
end_time = 6
dt = 6E-2
nl_abs_tol = 1E-8
timestep_tolerance = 1E-3
[]
[Outputs]
[./out]
type = CSV
execute_on = final
[../]
[]
[./advective_flux_calculator_0]
type = PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent
flux_limiter_type = superbee
fluid_component = 0
[../]
[./advective_flux_calculator_1]
type = PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent
flux_limiter_type = superbee
fluid_component = 1
[../]
(modules/porous_flow/test/tests/flux_limited_TVD_pflow/pffltvd_1D.i)/opt/civet/build_0/moose/modules/porous_flow/test/tests/flux_limited_TVD_pflow/pffltvd_1D.i
# Using flux-limited TVD advection ala Kuzmin and Turek, mploying PorousFlow Kernels and UserObjects, with superbee flux-limiter
# 1D version
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
xmin = 0
xmax = 1
[]
[GlobalParams]
PorousFlowDictator = dictator
gravity = '0 0 0'
[]
[Variables]
[./porepressure]
[../]
[./tracer]
[../]
[]
[ICs]
[./porepressure]
type = FunctionIC
variable = porepressure
function = '1 - x'
[../]
[./tracer]
type = FunctionIC
variable = tracer
function = 'if(x<0.1,0,if(x>0.3,0,1))'
[../]
[]
[Kernels]
[./mass0]
type = PorousFlowMassTimeDerivative
fluid_component = 0
variable = tracer
[../]
[./flux0]
type = PorousFlowFluxLimitedTVDAdvection
variable = tracer
advective_flux_calculator = advective_flux_calculator_0
[../]
[./mass1]
type = PorousFlowMassTimeDerivative
fluid_component = 1
variable = porepressure
[../]
[./flux1]
type = PorousFlowFluxLimitedTVDAdvection
variable = porepressure
advective_flux_calculator = advective_flux_calculator_1
[../]
[]
[BCs]
[./constant_injection_porepressure]
type = DirichletBC
variable = porepressure
value = 1
boundary = left
[../]
[./no_tracer_on_left]
type = DirichletBC
variable = tracer
value = 0
boundary = left
[../]
[./remove_component_1]
type = PorousFlowPiecewiseLinearSink
variable = porepressure
boundary = right
fluid_phase = 0
pt_vals = '0 1E3'
multipliers = '0 1E3'
mass_fraction_component = 1
use_mobility = true
flux_function = 1E3
[../]
[./remove_component_0]
type = PorousFlowPiecewiseLinearSink
variable = tracer
boundary = right
fluid_phase = 0
pt_vals = '0 1E3'
multipliers = '0 1E3'
mass_fraction_component = 0
use_mobility = true
flux_function = 1E3
[../]
[]
[Modules]
[./FluidProperties]
[./the_simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 2E9
thermal_expansion = 0
viscosity = 1.0
density0 = 1000.0
[../]
[../]
[]
[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'porepressure tracer'
number_fluid_phases = 1
number_fluid_components = 2
[../]
[./pc]
type = PorousFlowCapillaryPressureConst
[../]
[./advective_flux_calculator_0]
type = PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent
flux_limiter_type = superbee
fluid_component = 0
[../]
[./advective_flux_calculator_1]
type = PorousFlowAdvectiveFluxCalculatorSaturatedMultiComponent
flux_limiter_type = superbee
fluid_component = 1
[../]
[]
[Materials]
[./temperature]
type = PorousFlowTemperature
[../]
[./ppss]
type = PorousFlow1PhaseP
porepressure = porepressure
capillary_pressure = pc
[../]
[./massfrac]
type = PorousFlowMassFraction
mass_fraction_vars = tracer
[../]
[./simple_fluid]
type = PorousFlowSingleComponentFluid
fp = the_simple_fluid
phase = 0
[../]
[./relperm]
type = PorousFlowRelativePermeabilityConst
phase = 0
[../]
[./porosity]
type = PorousFlowPorosity
porosity_zero = 0.1
[../]
[./permeability]
type = PorousFlowPermeabilityConst
permeability = '1E-2 0 0 0 1E-2 0 0 0 1E-2'
[../]
[]
[Preconditioning]
active = basic
[./basic]
type = SMP
full = true
petsc_options = '-ksp_diagonal_scale -ksp_diagonal_scale_fix'
petsc_options_iname = '-pc_type -sub_pc_type -sub_pc_factor_shift_type -pc_asm_overlap'
petsc_options_value = ' asm lu NONZERO 2'
[../]
[./preferred_but_might_not_be_installed]
type = SMP
full = true
petsc_options_iname = '-pc_type -pc_factor_mat_solver_package'
petsc_options_value = ' lu mumps'
[../]
[]
[VectorPostprocessors]
[./tracer]
type = LineValueSampler
start_point = '0 0 0'
end_point = '1 0 0'
num_points = 11
sort_by = x
variable = tracer
[../]
[]
[Executioner]
type = Transient
solve_type = Newton
end_time = 6
dt = 6E-2
nl_abs_tol = 1E-8
timestep_tolerance = 1E-3
[]
[Outputs]
[./out]
type = CSV
execute_on = final
[../]
[]
note
For multi-phase situations you will need an advective flux calculator for each phase and each component, unless the phases are immiscible (each component exists in one phase only).
For example, in the case of 2 phases with 2 components, each potentially existing in both phases, there are 2 PorousFlow governing equations: one for each component. The equation for fluid component zero contains contributions from both phase 0 and phase 1. The equation for fluid component one contains contributions from both phase 0 and phase 1. So the Kernels will look like
[Kernels]
[./mass_component0]
type = PorousFlowMassTimeDerivative
variable = ppwater
fluid_component = 0
[../]
[./flux_component0_phase0]
type = PorousFlowFluxLimitedTVDAdvection
variable = ppwater
advective_flux_calculator = afc_component0_phase0
[../]
[./flux_component0_phase1]
type = PorousFlowFluxLimitedTVDAdvection
variable = ppwater
advective_flux_calculator = afc_component0_phase1
[../]
[./mass_component1]
type = PorousFlowMassTimeDerivative
variable = sgas
fluid_component = 1
[../]
[./flux_component1_phase0]
type = PorousFlowFluxLimitedTVDAdvection
variable = sgas
advective_flux_calculator = afc_component1_phase0
[../]
[./flux_component1_phase1]
type = PorousFlowFluxLimitedTVDAdvection
variable = sgas
advective_flux_calculator = afc_component1_phase1
[../]
[]
(modules/porous_flow/test/tests/pressure_pulse/pressure_pulse_1d_2phasePS_KT.i)/opt/civet/build_0/moose/modules/porous_flow/test/tests/pressure_pulse/pressure_pulse_1d_2phasePS_KT.i
# Pressure pulse in 1D with 2 phases, 2components - transient
# Using KT stabilization
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
xmin = 0
xmax = 100
[]
[GlobalParams]
PorousFlowDictator = dictator
gravity = '0 0 0'
[]
[Variables]
[./ppwater]
initial_condition = 2e6
[../]
[./sgas]
initial_condition = 0.3
[../]
[]
[AuxVariables]
[./massfrac_ph0_sp0]
initial_condition = 1
[../]
[./massfrac_ph1_sp0]
initial_condition = 0
[../]
[./ppgas]
family = MONOMIAL
order = FIRST
[../]
[]
[Kernels]
[./mass_component0]
type = PorousFlowMassTimeDerivative
variable = ppwater
fluid_component = 0
[../]
[./flux_component0_phase0]
type = PorousFlowFluxLimitedTVDAdvection
variable = ppwater
advective_flux_calculator = afc_component0_phase0
[../]
[./flux_component0_phase1]
type = PorousFlowFluxLimitedTVDAdvection
variable = ppwater
advective_flux_calculator = afc_component0_phase1
[../]
[./mass_component1]
type = PorousFlowMassTimeDerivative
variable = sgas
fluid_component = 1
[../]
[./flux_component1_phase0]
type = PorousFlowFluxLimitedTVDAdvection
variable = sgas
advective_flux_calculator = afc_component1_phase0
[../]
[./flux_component1_phase1]
type = PorousFlowFluxLimitedTVDAdvection
variable = sgas
advective_flux_calculator = afc_component1_phase1
[../]
[]
[AuxKernels]
[./ppgas]
type = PorousFlowPropertyAux
property = pressure
phase = 1
variable = ppgas
[../]
[]
[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'ppwater sgas'
number_fluid_phases = 2
number_fluid_components = 2
[../]
[./pc]
type = PorousFlowCapillaryPressureConst
pc = 1e5
[../]
[./afc_component0_phase0]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 0
phase = 0
flux_limiter_type = superbee
[../]
[./afc_component0_phase1]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 0
phase = 1
flux_limiter_type = superbee
[../]
[./afc_component1_phase0]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 1
phase = 0
flux_limiter_type = superbee
[../]
[./afc_component1_phase1]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 1
phase = 1
flux_limiter_type = superbee
[../]
[]
[Modules]
[./FluidProperties]
[./simple_fluid0]
type = SimpleFluidProperties
bulk_modulus = 2e9
density0 = 1000
thermal_expansion = 0
viscosity = 1e-3
[../]
[./simple_fluid1]
type = SimpleFluidProperties
bulk_modulus = 2e7
density0 = 1
thermal_expansion = 0
viscosity = 1e-5
[../]
[../]
[]
[Materials]
[./temperature]
type = PorousFlowTemperature
[../]
[./ppss]
type = PorousFlow2PhasePS
phase0_porepressure = ppwater
phase1_saturation = sgas
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
[../]
[./rightwater]
type = DirichletBC
boundary = right
value = 2e6
variable = ppwater
[../]
[]
[Preconditioning]
[./smp]
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
[]
[VectorPostprocessors]
[./pp]
type = LineValueSampler
sort_by = x
variable = 'ppwater ppgas'
start_point = '0 0 0'
end_point = '100 0 0'
num_points = 11
[../]
[]
[Outputs]
file_base = pressure_pulse_1d_2phasePS_KT
print_linear_residuals = false
[./csv]
type = CSV
execute_on = final
[../]
[]
and the UserObjects will look like
[./afc_component0_phase0]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 0
phase = 0
flux_limiter_type = superbee
[../]
[./afc_component0_phase1]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 0
phase = 1
flux_limiter_type = superbee
[../]
[./afc_component1_phase0]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 1
phase = 0
flux_limiter_type = superbee
[../]
[./afc_component1_phase1]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 1
phase = 1
flux_limiter_type = superbee
[../]
(modules/porous_flow/test/tests/pressure_pulse/pressure_pulse_1d_2phasePS_KT.i)/opt/civet/build_0/moose/modules/porous_flow/test/tests/pressure_pulse/pressure_pulse_1d_2phasePS_KT.i
# Pressure pulse in 1D with 2 phases, 2components - transient
# Using KT stabilization
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
xmin = 0
xmax = 100
[]
[GlobalParams]
PorousFlowDictator = dictator
gravity = '0 0 0'
[]
[Variables]
[./ppwater]
initial_condition = 2e6
[../]
[./sgas]
initial_condition = 0.3
[../]
[]
[AuxVariables]
[./massfrac_ph0_sp0]
initial_condition = 1
[../]
[./massfrac_ph1_sp0]
initial_condition = 0
[../]
[./ppgas]
family = MONOMIAL
order = FIRST
[../]
[]
[Kernels]
[./mass_component0]
type = PorousFlowMassTimeDerivative
variable = ppwater
fluid_component = 0
[../]
[./flux_component0_phase0]
type = PorousFlowFluxLimitedTVDAdvection
variable = ppwater
advective_flux_calculator = afc_component0_phase0
[../]
[./flux_component0_phase1]
type = PorousFlowFluxLimitedTVDAdvection
variable = ppwater
advective_flux_calculator = afc_component0_phase1
[../]
[./mass_component1]
type = PorousFlowMassTimeDerivative
variable = sgas
fluid_component = 1
[../]
[./flux_component1_phase0]
type = PorousFlowFluxLimitedTVDAdvection
variable = sgas
advective_flux_calculator = afc_component1_phase0
[../]
[./flux_component1_phase1]
type = PorousFlowFluxLimitedTVDAdvection
variable = sgas
advective_flux_calculator = afc_component1_phase1
[../]
[]
[AuxKernels]
[./ppgas]
type = PorousFlowPropertyAux
property = pressure
phase = 1
variable = ppgas
[../]
[]
[UserObjects]
[./dictator]
type = PorousFlowDictator
porous_flow_vars = 'ppwater sgas'
number_fluid_phases = 2
number_fluid_components = 2
[../]
[./pc]
type = PorousFlowCapillaryPressureConst
pc = 1e5
[../]
[./afc_component0_phase0]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 0
phase = 0
flux_limiter_type = superbee
[../]
[./afc_component0_phase1]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 0
phase = 1
flux_limiter_type = superbee
[../]
[./afc_component1_phase0]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 1
phase = 0
flux_limiter_type = superbee
[../]
[./afc_component1_phase1]
type = PorousFlowAdvectiveFluxCalculatorUnsaturatedMultiComponent
fluid_component = 1
phase = 1
flux_limiter_type = superbee
[../]
[]
[Modules]
[./FluidProperties]
[./simple_fluid0]
type = SimpleFluidProperties
bulk_modulus = 2e9
density0 = 1000
thermal_expansion = 0
viscosity = 1e-3
[../]
[./simple_fluid1]
type = SimpleFluidProperties
bulk_modulus = 2e7
density0 = 1
thermal_expansion = 0
viscosity = 1e-5
[../]
[../]
[]
[Materials]
[./temperature]
type = PorousFlowTemperature
[../]
[./ppss]
type = PorousFlow2PhasePS
phase0_porepressure = ppwater
phase1_saturation = sgas
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
[../]
[./rightwater]
type = DirichletBC
boundary = right
value = 2e6
variable = ppwater
[../]
[]
[Preconditioning]
[./smp]
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
[]
[VectorPostprocessors]
[./pp]
type = LineValueSampler
sort_by = x
variable = 'ppwater ppgas'
start_point = '0 0 0'
end_point = '100 0 0'
num_points = 11
[../]
[]
[Outputs]
file_base = pressure_pulse_1d_2phasePS_KT
print_linear_residuals = false
[./csv]
type = CSV
execute_on = final
[../]
[]
- D. Kuzmin and S. Turek.
High-resolution FEM-TVD shcemes based on a fully multidimensional flux limiter.
Journal of Computational Physics, 198:131–158, 2004.[BibTeX]
@article{KuzminTurek2004,
author = "Kuzmin, D. and Turek, S.",
title = "{High-resolution FEM-TVD shcemes based on a fully multidimensional flux limiter}",
journal = "Journal of Computational Physics",
volume = "198",
pages = "131--158",
year = "2004"
}