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.

commentnote

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)