Kokkos BCs System

Before reading this documentation, consider reading the following materials first for a better understanding of this documentation:

commentnote

Kokkos-MOOSE boundary conditions do not support automatic differention yet.

The basic design pattern of Kokkos-MOOSE kernels described in Kokkos Kernels System applies to the boundary conditions as well. You can create your own integrated and nodal boundary conditions by subclassing Moose::Kokkos::IntegratedBC and Moose::Kokkos::NodalBC, respectively, and following the same pattern with kernels. Especially, integrated boundary conditions have identical interfaces with kernels, so they will not be explained here in detail. See the following source codes of KokkosCoupledVarNeumannBC for an example of an integrated boundary condition:

Listing 1: The KokkosCoupledVarNeumannBC header file.


#pragma once

#include "KokkosIntegratedBC.h"

/**
 * Implements a Neumann BC where grad(u)=_coupled_var on the boundary.
 * Uses the term produced from integrating the diffusion operator by parts.
 */
class KokkosCoupledVarNeumannBC final
  : public Moose::Kokkos::IntegratedBC<KokkosCoupledVarNeumannBC>
{
public:
  static InputParameters validParams();

  KokkosCoupledVarNeumannBC(const InputParameters & parameters);

  KOKKOS_FUNCTION Real computeQpResidual(const unsigned int i,
                                         const unsigned int qp,
                                         ResidualDatum & datum) const;
  KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int i,
                                                const unsigned int j,
                                                const unsigned int jvar,
                                                const unsigned int qp,
                                                ResidualDatum & datum) const;

protected:
  /// Variable providing the value of grad(u) on the boundary.
  const Moose::Kokkos::VariableValue _coupled_var;

  /// The identifying number of the coupled variable
  const unsigned int _coupled_num;

  /// A coefficient that is multiplied with the residual contribution
  const Real _coef;

  /// Scale factor
  const Moose::Kokkos::VariableValue _scale_factor;
};

KOKKOS_FUNCTION inline Real
KokkosCoupledVarNeumannBC::computeQpResidual(const unsigned int i,
                                             const unsigned int qp,
                                             ResidualDatum & datum) const
{
  return -_scale_factor(datum, qp) * _coef * _test(datum, i, qp) * _coupled_var(datum, qp);
}

KOKKOS_FUNCTION inline Real
KokkosCoupledVarNeumannBC::computeQpOffDiagJacobian(const unsigned int i,
                                                    const unsigned int j,
                                                    const unsigned int jvar,
                                                    const unsigned int qp,
                                                    ResidualDatum & datum) const
{
  if (jvar == _coupled_num)
    return -_scale_factor(datum, qp) * _coef * _test(datum, i, qp) * _phi(datum, j, qp);
  else
    return 0;
}
(framework/include/kokkos/bcs/KokkosCoupledVarNeumannBC.h)

Listing 2: The KokkosCoupledVarNeumannBC source file.


#include "KokkosCoupledVarNeumannBC.h"

registerMooseObject("MooseApp", KokkosCoupledVarNeumannBC);

InputParameters
KokkosCoupledVarNeumannBC::validParams()
{
  InputParameters params = IntegratedBC::validParams();
  params.addRequiredCoupledVar("v", "Coupled variable setting the gradient on the boundary.");
  params.addCoupledVar("scale_factor", 1., "Scale factor to multiply the heat flux with");
  params.addParam<Real>(
      "coef", 1.0, "Coefficent ($\\sigma$) multiplier for the coupled force term.");
  params.addClassDescription("Imposes the integrated boundary condition "
                             "$\\frac{\\partial u}{\\partial n}=v$, "
                             "where $v$ is a variable.");
  return params;
}
KokkosCoupledVarNeumannBC::KokkosCoupledVarNeumannBC(const InputParameters & parameters)
  : IntegratedBC(parameters),
    _coupled_var(kokkosCoupledValue("v")),
    _coupled_num(coupled("v")),
    _coef(getParam<Real>("coef")),
    _scale_factor(kokkosCoupledValue("scale_factor"))
{
}
(framework/src/kokkos/bcs/KokkosCoupledVarNeumannBC.K)

On the other hand, nodal boundary conditions have slightly different interfaces. The hook methods for a nodal boundary condition have the following signatures:


KOKKOS_FUNCTION Real computeQpResidual(const ContiguousNodeID node) const;
KOKKOS_FUNCTION Real computeQpJacobian(const ContiguousNodeID node) const;
KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int jvar,
                                              const ContiguousNodeID node) const;

There is no datum object for a node; instead, only a single node index is passed as the argument. Instead of _current_node which is a pointer to the current libMesh node object, the node index can be used to retrieve mesh data from the Kokkos mesh object. Also, the dummy _qp indexing in the original MOOSE was dropped, although the functions still contain "Qp" in their names. The nodal variable values are accessed by the node index instead of the dummy _qp. As a result, the following residual function in DirichletBCBase:


Real
DirichletBCBase::computeQpResidual()
{
  return _u[_qp] - computeQpValue();
}

becomes the following in Moose::Kokkos::DirichletBCBase:


template <typename Derived>
KOKKOS_FUNCTION Real
DirichletBCBase<Derived>::computeQpResidual(const ContiguousNodeID node) const
{
  auto bc = static_cast<const Derived *>(this);

  return _u(node) - bc->computeValue(node);
}

Also note here the static implementation of computeValue using the Curiosuly Recurring Template Pattern (CRTP) which is originally a virtual function. It shows the principle of base class implementations in Kokkos-MOOSE.

See the following source codes of KokkosMatchedValueBC for another example of a nodal boundary condition:

Listing 3: The KokkosMatchedValueBC header file.


#pragma once

#include "KokkosNodalBC.h"

/**
 * Implements a simple coupled boundary condition where u=v on the boundary.
 */
class KokkosMatchedValueBC final : public Moose::Kokkos::NodalBC<KokkosMatchedValueBC>
{
public:
  static InputParameters validParams();

  KokkosMatchedValueBC(const InputParameters & parameters);

  KOKKOS_FUNCTION Real computeQpResidual(const ContiguousNodeID node) const;
  KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int jvar,
                                                const ContiguousNodeID node) const;

protected:
  const Moose::Kokkos::VariableNodalValue _v;

  /// The id of the coupled variable
  const unsigned int _v_num;
  /// Coefficient for primary variable
  const Real _u_coeff;
  /// Coefficient for coupled variable
  const Real _v_coeff;
};

KOKKOS_FUNCTION inline Real
KokkosMatchedValueBC::computeQpResidual(const ContiguousNodeID node) const
{
  return _u_coeff * _u(node) - _v_coeff * _v(node);
}

KOKKOS_FUNCTION inline Real
KokkosMatchedValueBC::computeQpOffDiagJacobian(const unsigned int jvar,
                                               const ContiguousNodeID /* node */) const
{
  if (jvar == _v_num)
    return -_v_coeff;
  else
    return 0;
}
(framework/include/kokkos/bcs/KokkosMatchedValueBC.h)

Listing 4: The KokkosMatchedValueBC source file.


#include "KokkosMatchedValueBC.h"

registerMooseObject("MooseApp", KokkosMatchedValueBC);

InputParameters
KokkosMatchedValueBC::validParams()
{
  InputParameters params = NodalBC::validParams();
  params.addRequiredCoupledVar("v", "The variable whose value we are to match.");
  params.addParam<Real>("u_coeff", 1.0, " A coefficient for primary variable u");
  params.addParam<Real>("v_coeff", 1.0, " A coefficient for coupled variable v");
  params.addClassDescription("Implements a NodalBC which equates two different Variables' values "
                             "on a specified boundary.");
  return params;
}

KokkosMatchedValueBC::KokkosMatchedValueBC(const InputParameters & parameters)
  : NodalBC(parameters),
    _v(kokkosCoupledNodalValue("v")),
    _v_num(coupled("v")),
    _u_coeff(getParam<Real>("u_coeff")),
    _v_coeff(getParam<Real>("v_coeff"))
{
}
(framework/src/kokkos/bcs/KokkosMatchedValueBC.K)

Available Objects

  • Moose App
  • KokkosCoupledVarNeumannBCImposes the integrated boundary condition , where is a variable.
  • KokkosDirichletBCImposes the essential boundary condition , where is a constant, controllable value.
  • KokkosMatchedValueBCImplements a NodalBC which equates two different Variables' values on a specified boundary.
  • KokkosNeumannBCImposes the integrated boundary condition , where is a constant, controllable value.
  • KokkosPostprocessorNeumannBCNeumann boundary condition with value prescribed by a Postprocessor value.
  • KokkosVacuumBCVacuum boundary condition for diffusion.
  • Thermal Hydraulics App
  • KokkosRadiativeHeatFluxBCRadiative heat transfer boundary condition for a plate heat structure
  • Heat Transfer App
  • KokkosConvectiveHeatFluxBCConvective heat transfer boundary condition with temperature and heat transfer coefficent given by material properties.
  • KokkosCoupledConvectiveHeatFluxBCConvective heat transfer boundary condition with temperature and heat transfer coefficent given by auxiliary variables.