LinearFVBCs System

The difference between LinearFVBCs and FVBCs is that the boundary quantities computed by the former (boundary values, gradients, etc.) are used in routines within linear FV kernels. This is due to the fact that boundary conditions may need to be applied in different manners for different terms in the partial differential equation. This means that the LinearFVBCs only provide objects to specify these boundary quantities, and would not contribute to the system matrix and right hand side directly (only through kernels).

For more information on general design choices in this setting click here

LinearFVBCs block

FVM boundary conditions are added to simulation input files in the LinearFVBCs as in the example below.

Example of the LinearFVBCs block in a MOOSE input file.

[LinearFVBCs]
  [inflow]
    type = LinearFVAdvectionDiffusionFunctorDirichletBC
    variable = u
    boundary = "left"
    functor = analytic_solution
  []
  [outflow]
    type = LinearFVAdvectionDiffusionOutflowBC
    variable = u
    boundary = "right"
    use_two_term_expansion = false
  []
[]
(moose/test/tests/linearfvkernels/advection/advection-1d.i)

In this example input, an advection equation with Dirichlet boundary condition on the left and outflow boundary conditions on the right is solved. To understand the differences between these two boundary conditions, let's start with the advection equation:

with denoting the velocity vector, the solution, and a potentially space-dependent source term. The boundary condition on the left can be expressed as:

while the outflow boundary expresses outward advection with the solution value on the boundary and a predefined velocity.

Both boundary conditions can be applied in an integral sense through the discretized advection term on the cell adjacent to the boundary:

where the index denotes internal faces of the cell, while denotes the only face on the boundary. This means that the only thing we need to supply to this formula is a way to compute the contributions to the system matrix and right hand side from the boundary value . For example for the Dirichlet boundary , while for the outflow boundary it can be either the cell centroid value () or an extrapolated value. This also means that the Dirichlet boundary contributes to the right hand side of the system only, whereas the outflow boundary condition can contribute to both.

Functions to override:

Different linear finite volume kernels might use the quantities provided by these boundary conditions differently, but these APIs should be implemented for boundary conditions of linear systems:

  • computeBoundaryValue computes the boundary value of the field.

  • computeBoundaryNormalGradient computes the normal gradient of the variable on this boundary.

For derived classes of linear system boundary conditions, we recommend following the same design pattern as the LinearAdvectionDiffusionBC parent class. For all boundary conditions (Neumann and Dirichlet) for an advection-diffusion problem, we implemented the following four APIs:

  • computeBoundaryValueMatrixContribution computes the matrix contribution that would come from the boundary value of the field, extensively used within advection kernels. For example, on an outflow boundary in an advection problem, without using linear extrapolation, one can use the cell value as an approximation for the boundary value: . In this case, we can treat the outflow term implicitly by adding a term to the matrix which comes from outward flux term. This function will return (as it is just the cell value) and the multipliers are added in the advection kernel.

  • computeBoundaryValueRHSContribution computes the right hand side contributions for terms that need the boundary value of the field, extensively used within advection kernels. Using the same example as above, by employing an extrapolation to the boundary face to determine the boundary value, we get the following expression: , where is the vector pointing to the face center from the cell center. In this case, besides the same matrix contribution as above, we need to add the following term to the right hand side: . Therefore, this function returns (as it is just the value contribution) and the other multipliers are added in the advection kernel.

  • computeBoundaryGradientMatrixContribution computes the matrix contributions for terms that need the boundary gradient of the field, extensively used within diffusion kernels. Let us take a Dirichlet boundary condition and a diffusion kernel for example. The integral form of the diffusion term requires the computation of the surface normal gradient which can be approximated on an orthogonal grid as: which means that the term including can go to the matrix of coefficients. Therefore, this function will return with additional multipliers added at the kernel level.

  • computeBoundaryGradientRHSContribution computes the right hand side contributions for terms that need the boundary gradient of the field, extensively used within diffusion kernels. Using the same example as above, the remaining part of the expression belongs to the right hand side meaning that a term will be added with additional multipliers applied at the kernel level.

LinearFVBCs source code: LinearFVAdvectionDiffusionFunctorDirichletBC

LinearFVAdvectionDiffusionFunctorDirichletBC object assigns a value on a boundary. This value is computed using a moose functor. For more information on the functor system in moose, see Functor system.

Example source code for LinearFVAdvectionDiffusionFunctorDirichletBC.

#include "LinearFVAdvectionDiffusionFunctorDirichletBC.h"

registerMooseObject("MooseApp", LinearFVAdvectionDiffusionFunctorDirichletBC);

InputParameters
LinearFVAdvectionDiffusionFunctorDirichletBC::validParams()
{
  InputParameters params = LinearFVAdvectionDiffusionBC::validParams();
  params.addClassDescription(
      "Adds a dirichlet BC which can be used for the assembly of linear "
      "finite volume system and whose face values are determined using a functor. This kernel is "
      "only designed to work with advection-diffusion problems.");
  params.addRequiredParam<MooseFunctorName>("functor", "The functor for this boundary condition.");
  return params;
}

LinearFVAdvectionDiffusionFunctorDirichletBC::LinearFVAdvectionDiffusionFunctorDirichletBC(
    const InputParameters & parameters)
  : LinearFVAdvectionDiffusionBC(parameters), _functor(getFunctor<Real>("functor"))
{
}

Real
LinearFVAdvectionDiffusionFunctorDirichletBC::computeBoundaryValue() const
{
  return _functor(singleSidedFaceArg(_current_face_info), determineState());
}

Real
LinearFVAdvectionDiffusionFunctorDirichletBC::computeBoundaryNormalGradient() const
{
  const auto elem_arg = makeElemArg(_current_face_type == FaceInfo::VarFaceNeighbors::ELEM
                                        ? _current_face_info->elemPtr()
                                        : _current_face_info->neighborPtr());
  const Real distance = computeCellToFaceDistance();
  return (_functor(singleSidedFaceArg(_current_face_info), determineState()) -
          raw_value(_var(elem_arg, determineState()))) /
         distance;
}

Real
LinearFVAdvectionDiffusionFunctorDirichletBC::computeBoundaryValueMatrixContribution() const
{
  // Ths will not contribute to the matrix from the value considering that
  // the value is independent of the solution.
  return 0.0;
}

Real
LinearFVAdvectionDiffusionFunctorDirichletBC::computeBoundaryValueRHSContribution() const
{
  // Fetch the boundary value from the provided functor.
  return _functor(singleSidedFaceArg(_current_face_info), determineState());
}

Real
LinearFVAdvectionDiffusionFunctorDirichletBC::computeBoundaryGradientMatrixContribution() const
{
  // The implicit term from the central difference approximation of the normal
  // gradient.
  return 1.0 / computeCellToFaceDistance();
}

Real
LinearFVAdvectionDiffusionFunctorDirichletBC::computeBoundaryGradientRHSContribution() const
{
  // The boundary term from the central difference approximation of the
  // normal gradient.
  return _functor(singleSidedFaceArg(_current_face_info), determineState()) /
         computeCellToFaceDistance();
}
(moose/framework/src/linearfvbcs/LinearFVAdvectionDiffusionFunctorDirichletBC.C)

Available Objects

  • Moose App
  • LinearFVAdvectionDiffusionFunctorDirichletBCAdds a dirichlet BC which can be used for the assembly of linear finite volume system and whose face values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.
  • LinearFVAdvectionDiffusionOutflowBCAdds a boundary condition which represents a surface with outflowing material with a constant velocity. This kernel is only compatible with advection-diffusion problems.