FVInterfaceKernels System
For an overview of MOOSE FV please see Finite Volume Design Decisions in MOOSE.
FVInterfaceKernels
are meant to communicate data at interfaces between subdomains. An FVInterfaceKernel
may contribute to the residuals/Jacobians of a single variable, specified with the parameter variable1
, or to multiple variables by also using the variable2
parameter. There are two additional critical/required parameters: subdomain1
and subdomain2
. In cases for which an FVInterfaceKernel
is operating on two variables, subdomain1
should correspond to the subdomain(s) neighboring the boundary
parameter that variable1
lives on, and similarly for subdomain2
and variable2
. By checking the subdomain
parameters against the subdomain IDs of the FaceInfo::elem
and FaceInfo::neighbor
members a FVInterfaceKernel
developer can be sure that they are fetching and using sensical data. For instance, a developer may want to create an FVInterfaceKernel
that uses prop1
on the subdomain1
side of the boundary
and prop2
on the subdomain2
side of the boundary. However, MOOSE only provides these APIs for fetching material properties: get(AD)MaterialProperty
and getNeighbor(AD)MaterialProperty
. The return value of get(AD)MaterialProperty
will always correspond to a material property evaluation on the FaceInfo::elem
side of a (inter)face, while the return value of getNeighbor(AD)MaterialProperty
will always correspond to a material property evaluation on the FaceInfo::neighbor
side of a (inter)face. However, when moving along an interface, it is possible that the FaceInfo::elem
side of the interface is sometimes the subdomain1
side and sometimes the subdomain2
side. So making use of the subdomain
parameters, we provide a protected method called elemIsOne()
that returns a boolean indicating whether the FaceInfo::elem
side of the interface corresponds to the subdomain1
side of the interface. This allows the developer to write code like the following:
FVFooInterface::FVFooInterface(const InputParameters & params)
: FVInterfaceKernel(params),
_coeff1_elem(getADMaterialProperty<Real>("coeff1")),
_coeff2_elem(getADMaterialProperty<Real>("coeff2")),
_coeff1_neighbor(getNeighborADMaterialProperty<Real>("coeff1")),
_coeff2_neighbor(getNeighborADMaterialProperty<Real>("coeff2"))
{
}
ADReal
FVFooInterface::computeQpResidual()
{
const auto & coef_elem = elemIsOne() ? _coeff1_elem : _coeff2_elem;
const auto & coef_neighbor = elemIsOne() ? _coeff2_neighbor : _coeff1_neighbor;
/// Code that uses coef_elem and coef_neighbor
}
and have confidence that they have good data in coef_elem
and coef_neighbor
and have clarity about what is happening in their code.
When using an FVInterfaceKernel which connects variables that belong to different nonlinear systems, create two kernels with flipped variable and material property parameters. The reason behind this is that the interface kernel will only contribute to the system which variable1
belongs to. For an example, see:
[Mesh<<<{"href": "../Mesh/index.html"}>>>]
[gmg]
type = CartesianMeshGenerator<<<{"description": "This CartesianMeshGenerator creates a non-uniform Cartesian mesh.", "href": "../../source/meshgenerators/CartesianMeshGenerator.html"}>>>
dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 1
ix<<<{"description": "Number of grids in all intervals in the X direction (default to all one)"}>>> = '50 50'
dx<<<{"description": "Intervals in the X direction"}>>> = '1 1'
subdomain_id<<<{"description": "Block IDs (default to all zero)"}>>> = '0 1'
[]
[sds]
type = SideSetsBetweenSubdomainsGenerator<<<{"description": "MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains.", "href": "../../source/meshgenerators/SideSetsBetweenSubdomainsGenerator.html"}>>>
input<<<{"description": "The mesh we want to modify"}>>> = gmg
new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = 'between'
paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = '1'
primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = '0'
[]
[]
[Problem<<<{"href": "../Problem/index.html"}>>>]
nl_sys_names = 'u v'
error_on_jacobian_nonzero_reallocation = true
[]
[Variables<<<{"href": "../Variables/index.html"}>>>]
[u]
type = MooseVariableFVReal<<<{"description": "Base class for Moose variables. This should never be the terminal object type", "href": "../../source/variables/MooseVariableFV.html"}>>>
solver_sys<<<{"description": "If this variable is a solver variable, this is the solver system to which it should be added."}>>> = 'u'
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = 0
[]
[v]
type = MooseVariableFVReal<<<{"description": "Base class for Moose variables. This should never be the terminal object type", "href": "../../source/variables/MooseVariableFV.html"}>>>
solver_sys<<<{"description": "If this variable is a solver variable, this is the solver system to which it should be added."}>>> = 'v'
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = 1
[]
[]
[FVKernels<<<{"href": "../FVKernels/index.html"}>>>]
[diff_u]
type = FVDiffusion<<<{"description": "Computes residual for diffusion operator for finite volume method.", "href": "../../source/fvkernels/FVDiffusion.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = u
coeff<<<{"description": "diffusion coefficient. A functor is any of the following: a variable, a functor material property, a function, a post-processor, or a number."}>>> = 3.0
[]
[force_u]
type = FVBodyForce<<<{"description": "Demonstrates the multiple ways that scalar values can be introduced into finite volume kernels, e.g. (controllable) constants, functions, and postprocessors.", "href": "../../source/fvkernels/FVBodyForce.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = u
function<<<{"description": "A function that describes the body force"}>>> = 5
[]
[diff_v]
type = FVDiffusion<<<{"description": "Computes residual for diffusion operator for finite volume method.", "href": "../../source/fvkernels/FVDiffusion.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = v
coeff<<<{"description": "diffusion coefficient. A functor is any of the following: a variable, a functor material property, a function, a post-processor, or a number."}>>> = 1.0
[]
[force_v]
type = FVBodyForce<<<{"description": "Demonstrates the multiple ways that scalar values can be introduced into finite volume kernels, e.g. (controllable) constants, functions, and postprocessors.", "href": "../../source/fvkernels/FVBodyForce.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = v
function<<<{"description": "A function that describes the body force"}>>> = 5
[]
[]
[FVInterfaceKernels<<<{"href": "index.html"}>>>]
[diff_ik]
type = FVDiffusionInterface<<<{"description": "Computes the residual for diffusion operator across an interface for the finite volume method.", "href": "../../source/fviks/FVDiffusionInterface.html"}>>>
variable1<<<{"description": "The name of the first variable that this interface kernel applies to"}>>> = u
variable2<<<{"description": "The name of the second variable that this interface kernel applies to. If not supplied, variable1 will be used."}>>> = v
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'between'
coeff1<<<{"description": "The diffusion coefficient on the 1st subdomain"}>>> = 3
coeff2<<<{"description": "The diffusion coefficient on the 2nd subdomain"}>>> = 1
subdomain1<<<{"description": "The subdomains on the 1st side of the boundary."}>>> = 0
subdomain2<<<{"description": "The subdomains on the 2nd side of the boundary."}>>> = 1
[]
[diff_ik_v]
type = FVDiffusionInterface<<<{"description": "Computes the residual for diffusion operator across an interface for the finite volume method.", "href": "../../source/fviks/FVDiffusionInterface.html"}>>>
variable1<<<{"description": "The name of the first variable that this interface kernel applies to"}>>> = v
variable2<<<{"description": "The name of the second variable that this interface kernel applies to. If not supplied, variable1 will be used."}>>> = u
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'between'
coeff1<<<{"description": "The diffusion coefficient on the 1st subdomain"}>>> = 1
coeff2<<<{"description": "The diffusion coefficient on the 2nd subdomain"}>>> = 3
subdomain1<<<{"description": "The subdomains on the 1st side of the boundary."}>>> = 1
subdomain2<<<{"description": "The subdomains on the 2nd side of the boundary."}>>> = 0
[]
[]
[FVBCs<<<{"href": "../FVBCs/index.html"}>>>]
[left_u]
type = FVDirichletBC<<<{"description": "Defines a Dirichlet boundary condition for finite volume method.", "href": "../../source/fvbcs/FVDirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = u
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = left
value<<<{"description": "value to enforce at the boundary face"}>>> = 0
[]
[right_v]
type = FVDirichletBC<<<{"description": "Defines a Dirichlet boundary condition for finite volume method.", "href": "../../source/fvbcs/FVDirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = v
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = right
value<<<{"description": "value to enforce at the boundary face"}>>> = 1
[]
[]
[Preconditioning<<<{"href": "../Preconditioning/index.html"}>>>]
[u]
type = SMP<<<{"description": "Single matrix preconditioner (SMP) builds a preconditioner using user defined off-diagonal parts of the Jacobian.", "href": "../../source/preconditioners/SingleMatrixPreconditioner.html"}>>>
nl_sys<<<{"description": "The nonlinear system whose linearization this preconditioner should be applied to."}>>> = u
petsc_options<<<{"description": "Singleton PETSc options"}>>> = '-snes_monitor'
petsc_options_iname<<<{"description": "Names of PETSc name/value pairs"}>>> = '-pc_type -pc_hypre_type'
petsc_options_value<<<{"description": "Values of PETSc name/value pairs (must correspond with \"petsc_options_iname\""}>>> = 'hypre boomeramg'
[]
[v]
type = SMP<<<{"description": "Single matrix preconditioner (SMP) builds a preconditioner using user defined off-diagonal parts of the Jacobian.", "href": "../../source/preconditioners/SingleMatrixPreconditioner.html"}>>>
nl_sys<<<{"description": "The nonlinear system whose linearization this preconditioner should be applied to."}>>> = v
petsc_options<<<{"description": "Singleton PETSc options"}>>> = '-snes_monitor'
petsc_options_iname<<<{"description": "Names of PETSc name/value pairs"}>>> = '-pc_type -pc_hypre_type'
petsc_options_value<<<{"description": "Values of PETSc name/value pairs (must correspond with \"petsc_options_iname\""}>>> = 'hypre boomeramg'
[]
[]
[Executioner<<<{"href": "../Executioner/index.html"}>>>]
type = SteadySolve2
solve_type = 'NEWTON'
first_nl_sys_to_solve = 'u'
second_nl_sys_to_solve = 'v'
number_of_iterations = 200
nl_abs_tol = 1e-10
[]
[Outputs<<<{"href": "../Outputs/index.html"}>>>]
print_nonlinear_residuals<<<{"description": "Enable printing of nonlinear residuals to the screen (Console)"}>>> = false
print_linear_residuals<<<{"description": "Enable printing of linear residuals to the screen (Console)"}>>> = false
exodus<<<{"description": "Output the results using the default settings for Exodus output."}>>> = true
[]
(moose/test/tests/fviks/diffusion/multisystem.i)