Kokkos UserObjects System

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

Currently, the following types of user objects are supported in Kokkos-MOOSE including their derivatives (postprocessors, vector postprocessors, and reporters), which all should be registered with registerKokkosUserObject():

  • Moose::Kokkos::ElementUserObject

  • Moose::Kokkos::SideUserObject

  • Moose::Kokkos::NodalUserObject

The hook method execute() is now defined as an inlined public method with the following signature:


template <typename Derived>
KOKKOS_FUNCTION void execute(Datum & datum) const;

For other CPU APIs, Kokkos-MOOSE user objects share the same interface with the original MOOSE objects except threadJoin(), which is undefined in Kokkos-MOOSE user objects as they have separate parallel loops dispatched by Kokkos.

commentnote

The dependencies between Kokkos-MOOSE user objects and the original MOOSE user objects are not automatically respected, and it is highly discouraged to have dependencies between them. However, if you need objects from both of those categories to be executed in a specific order, you can manually specify the execution_order_group parameter. A negative group may be specified to execute before the default group (0). For the same group, Kokkos-MOOSE user objects are always executed prior to the original MOOSE user objects. For this reason, the Kokkos version of general user object (Moose::Kokkos::GeneralUserObject) is still provided in case there is a general user object having dependencies with other Kokkos-MOOSE user objects, although it does not execute any parallel loop. A Kokkos-MOOSE general user object should be registered with the standard registerMooseObject() macro.

commentnote

Different types of Kokkos-MOOSE user objects are executed without any predefined order (dependencies are still respected).

Reducers

Postprocessors, vector postprocessors, and reporters often perform calculations that aggregate data. Such aggregation calculation is also known as reduction operation. If your calculation is considered more suitable for a reduction operation than an ordinary parallel operation, you can make your user object a Reducer object by defining different hook methods, which will use a different parallelization scheme from regular parallel objects.

Reduction operations are not trivial on GPU due to its massively parallel nature that requires the data race to be carefully managed. Therefore, you cannot directly perform reduction operations on your own variables. Instead, the reduction operations should be performed on a preallocated buffer defined by the reducer. Every reducer should allocate the buffer with the desired size by calling allocateReductionBuffer() prior to the calculation, which can be done either in the constructor or in the initialize() hook. It allocates _reduction_buffer, which is a one-dimensional Kokkos::View defined in the CPU space. The hook method is now named as reduce() and receives an additional argument result that points to a buffer where you need to perform your reduction operations. This buffer has the same size with _reduction_buffer, but it is a buffer internally defined by Kokkos and is different from _reduction_buffer:


template <typename Derived>
KOKKOS_FUNCTION void reduce(Datum & datum, Real * result) const;

A reducer also requires two more hook methods to be defined in your derived object, which are join() and init(). They have the following signatures:


template <typename Derived>
KOKKOS_FUNCTION void join(Real * result, const Real * source) const;
template <typename Derived>
KOKKOS_FUNCTION void init(Real * result) const;

join() can be considered as a replacement of threadJoin() in the original MOOSE objects. It combines the values of source into result and should typically implement the same reduction operation with reduce(). init() can be considered as a replacement of initialize() in the original MOOSE objects where you used to initialize your reduction variables. It initializes the Kokkos internal buffer on GPU. Note that initializing _reduction_buffer has no effect on GPU and thus is not required. Once the calculation is complete, the results are stored in _reduction_buffer. You can process the values stored in _reduction_buffer in the finalize() or getValue() hook to compute final values.

It is important to note that the buffer is always provided as the Real type. If you need to implement a reduction operation for a data type other than Real, you need to do type casting or bit casting of the given buffer to the desired type. Typically, the data types used for reductions other than Real are boolean and integer. Boolean operations can be performed with Real, and the integers in the range can be exactly represented by Real. Therefore, the need for a bit-level manipulation will be highly unlikely.

See the following source codes of KokkosIntegralPostprocessor for an example of a postprocessor:

Listing 1: The KokkosIntegralPostprocessor header file.


#pragma once

#include "KokkosElementPostprocessor.h"
#include "KokkosSidePostprocessor.h"

template <typename Base>
class KokkosIntegralPostprocessor : public Base
{
public:
  static InputParameters validParams();

  KokkosIntegralPostprocessor(const InputParameters & parameters);

  virtual void initialize() override;
  virtual Real getValue() const override;
  virtual void finalize() override;

  template <typename Derived>
  KOKKOS_FUNCTION void reduce(Datum & datum, Real * result) const;
  template <typename Derived>
  KOKKOS_FUNCTION void join(Real * result, const Real * source) const;
  template <typename Derived>
  KOKKOS_FUNCTION void init(Real * result) const;

protected:
  const bool _average;
};

template <typename Base>
template <typename Derived>
KOKKOS_FUNCTION void
KokkosIntegralPostprocessor<Base>::reduce(Datum & datum, Real * result) const
{
  Real sum = 0;
  Real vol = 0;

  for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
  {
    sum += datum.JxW(qp) * static_cast<const Derived *>(this)->computeQpIntegral(qp, datum);
    vol += datum.JxW(qp);
  }

  result[0] += sum;

  if (_average)
    result[1] += vol;
}

template <typename Base>
template <typename Derived>
KOKKOS_FUNCTION void
KokkosIntegralPostprocessor<Base>::join(Real * result, const Real * source) const
{
  result[0] += source[0];

  if (_average)
    result[1] += source[1];
}

template <typename Base>
template <typename Derived>
KOKKOS_FUNCTION void
KokkosIntegralPostprocessor<Base>::init(Real * result) const
{
  result[0] = 0;

  if (_average)
    result[1] = 0;
}

typedef KokkosIntegralPostprocessor<Moose::Kokkos::ElementPostprocessor>
    KokkosElementIntegralPostprocessor;
typedef KokkosIntegralPostprocessor<Moose::Kokkos::SidePostprocessor>
    KokkosSideIntegralPostprocessor;
(framework/include/kokkos/postprocessors/KokkosIntegralPostprocessor.h)

Listing 2: The KokkosIntegralPostprocessor source file.


#include "KokkosIntegralPostprocessor.h"

template <typename Base>
InputParameters
KokkosIntegralPostprocessor<Base>::validParams()
{
  InputParameters params = Base::validParams();
  params.addParam<bool>("average", false, "Whether to compute volume average");
  return params;
}

template <typename Base>
KokkosIntegralPostprocessor<Base>::KokkosIntegralPostprocessor(const InputParameters & parameters)
  : Base(parameters), _average(Base::template getParam<bool>("average"))
{
}

template <typename Base>
void
KokkosIntegralPostprocessor<Base>::initialize()
{
  Base::allocateReductionBuffer(_average ? 2 : 1);
}

template <typename Base>
Real
KokkosIntegralPostprocessor<Base>::getValue() const
{
  return _average ? Base::_reduction_buffer[0] / Base::_reduction_buffer[1]
                  : Base::_reduction_buffer[0];
}

template <typename Base>
void
KokkosIntegralPostprocessor<Base>::finalize()
{
  Base::gatherSum(Base::_reduction_buffer[0]);

  if (_average)
    Base::gatherSum(Base::_reduction_buffer[1]);
}

template class KokkosIntegralPostprocessor<Moose::Kokkos::ElementPostprocessor>;
template class KokkosIntegralPostprocessor<Moose::Kokkos::SidePostprocessor>;
(framework/src/kokkos/postprocessors/KokkosIntegralPostprocessor.K)
commentnote

The reporter values defined by Kokkos-MOOSE postprocessors, vector postprocessors, and reporters are stored in the same database with the original MOOSE objects, so they can be retrieved through the existing interfaces and their names cannot overlap.

Performance Considerations

The Kokkos Reducer concept leveraged to implement Kokkos-MOOSE reducers is suitable for small arrays and "dense" reduction operations. Assume you are reducing a large array, where a single call to reduce() only accumulates values to one or a few entries of the array at most. This can be considered as a "sparse" reduction operation and is not suitable for a reducer. A massively-parallel reduction is implemented by many partial reductions where many temporary buffers are internally created and initialized. Even though most of the entries of a temporary buffer are unused in each partial reduction, it still has to initialize and join all the entries. As a result, the cost of initialization and join can overwhelm the gain from parallelization. In addition, the temporary buffers are typically allocated in configurable caches with limited sizes like shared memory in CUDA, so small arrays are desired. If the array being reduced is too large, you will likely get an error like Kokkos::Impl::ParallelReduce<Cuda> requested too much L0 scratch memory. Such type of reduction operation is therefore better be implemented using atomic operations in an ordinary parallel loop instead of a reduction loop. See the following example of KokkosExtraIDIntegralVectorPostprocessor, which implements both atomic addition and reduction algorithms and provides users an option to choose the calculation mode:

Listing 3: The KokkosExtraIDIntegralVectorPostprocessor header file.


#pragma once

#include "KokkosElementVectorPostprocessor.h"

#include "MooseMesh.h"

class KokkosExtraIDIntegralVectorPostprocessor : public Moose::Kokkos::ElementVectorPostprocessor
{
  template <typename T>
  using Array = Moose::Kokkos::Array<T>;

  template <typename T>
  using MaterialProperty = Moose::Kokkos::MaterialProperty<T>;

  using VariableValue = Moose::Kokkos::VariableValue;

public:
  static InputParameters validParams();
  KokkosExtraIDIntegralVectorPostprocessor(const InputParameters & parameters);

  virtual void initialSetup() override;
  virtual void initialize() override;
  virtual void compute() override;
  virtual void finalize() override;

  template <typename Derived>
  KOKKOS_FUNCTION void join(Real * result, const Real * source) const;
  template <typename Derived>
  KOKKOS_FUNCTION void init(Real * result) const;
  template <typename Derived>
  KOKKOS_FUNCTION void reduce(Datum & datum, Real * result) const;
  template <typename Derived>
  KOKKOS_FUNCTION void execute(Datum & datum) const;

protected:
  /// MOOSE mesh
  const MooseMesh & _mesh;
  /// Whether or not to compute volume average
  const bool _average;
  /// Calculation mode
  const MooseEnum _mode;
  /// Number of variables to be integrated
  const unsigned int _nvar;
  /// Number of material properties to be integrated
  const unsigned int _nprop;
  /// Name of material properties
  const std::vector<MaterialPropertyName> _prop_names;
  /// Extra IDs in use
  const std::vector<ExtraElementIDName> _extra_id;
  /// Number of extra IDs in use
  const unsigned int _n_extra_id;
  /// Map of element IDs to parsed vpp ids
  std::unordered_map<dof_id_type, dof_id_type> _unique_vpp_id_map;
  /// Map of contiguous element IDs to parsed vpp ids for device
  Array<Array<dof_id_type>> _unique_vpp_ids;
  /// Quadrature point values of coupled MOOSE variables
  VariableValue _var_values;
  /// Material properties to be integrated
  Array<MaterialProperty<Real>> _props;
  /// Vector holding the volume of extra IDs
  Array<Real> _volumes;
  /// Vectors holding integrals over extra IDs
  Array<Array<Real>> _integrals;
  /// Vectors holding extra IDs
  std::vector<VectorPostprocessorValue *> _extra_ids;
  /// Size of the vector
  dof_id_type _vector_size;
  /// Sum cache size
  static constexpr unsigned int _cache_size = 10;
};

template <typename Derived>
KOKKOS_FUNCTION void
KokkosExtraIDIntegralVectorPostprocessor::join(Real * result, const Real * source) const
{
  auto size = _vector_size * (_nvar + _nprop + _average);

  for (decltype(size) i = 0; i < size; ++i)
    result[i] += source[i];
}

template <typename Derived>
KOKKOS_FUNCTION void
KokkosExtraIDIntegralVectorPostprocessor::init(Real * result) const
{
  auto size = _vector_size * (_nvar + _nprop + _average);

  for (decltype(size) i = 0; i < size; ++i)
    result[i] = 0;
}

template <typename Derived>
KOKKOS_FUNCTION void
KokkosExtraIDIntegralVectorPostprocessor::reduce(Datum & datum, Real * result) const
{
  const auto ipos = _unique_vpp_ids[datum.subdomain()](datum.elemID());
  const auto & var = _var_values.variable();
  const auto subdomain = datum.subdomain();

  Real sum[_cache_size] = {0};
  Real vol = 0;

  for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
  {
    const auto JxW = datum.JxW(qp);

    unsigned int i = 0;

    for (unsigned int ivar = 0; ivar < _nvar; ++ivar, ++i)
      if (kokkosSystem(var.sys(ivar)).isVariableActive(var.var(ivar), subdomain))
        sum[i] += JxW * _var_values(datum, qp, ivar);

    for (unsigned int iprop = 0; iprop < _nprop; ++iprop, ++i)
      sum[i] += JxW * _props[iprop](datum, qp);

    vol += JxW;
  }

  for (unsigned int i = 0; i < _nvar + _nprop; ++i)
    result[ipos + i * _vector_size] += sum[i];

  if (_average)
    result[ipos + (_nvar + _nprop) * _vector_size] += vol;
}

template <typename Derived>
KOKKOS_FUNCTION void
KokkosExtraIDIntegralVectorPostprocessor::execute(Datum & datum) const
{
  const auto ipos = _unique_vpp_ids[datum.subdomain()](datum.elemID());
  const auto & var = _var_values.variable();
  const auto subdomain = datum.subdomain();

  Real sum[_cache_size] = {0};
  Real vol = 0;

  for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
  {
    const auto JxW = datum.JxW(qp);

    unsigned int i = 0;

    for (unsigned int ivar = 0; ivar < _nvar; ++ivar, ++i)
      if (kokkosSystem(var.sys(ivar)).isVariableActive(var.var(ivar), subdomain))
        sum[i] += JxW * _var_values(datum, qp, ivar);

    for (unsigned int iprop = 0; iprop < _nprop; ++iprop, ++i)
      sum[i] += JxW * _props[iprop](datum, qp);

    vol += JxW;
  }

  for (unsigned int i = 0; i < _nvar + _nprop; ++i)
    Kokkos::atomic_add(&_integrals[i][ipos], sum[i]);

  if (_average)
    Kokkos::atomic_add(&_volumes[ipos], vol);
}
(framework/include/kokkos/vectorpostprocessors/KokkosExtraIDIntegralVectorPostprocessor.h)

Listing 4: The KokkosExtraIDIntegralVectorPostprocessor source file.


#include "KokkosExtraIDIntegralVectorPostprocessor.h"

#include "MooseVariable.h"
#include "MooseMesh.h"
#include "MooseMeshUtils.h"

#include "libmesh/mesh_base.h"

registerKokkosUserObject("MooseApp", KokkosExtraIDIntegralVectorPostprocessor);

InputParameters
KokkosExtraIDIntegralVectorPostprocessor::validParams()
{
  InputParameters params = ElementVectorPostprocessor::validParams();
  params.addCoupledVar("variable",
                       "The names of the variables that this VectorPostprocessor operates on");
  params.addParam<std::vector<MaterialPropertyName>>(
      "mat_prop", "The names of material properties that this VectorPostprocessor operates on");
  params.addRequiredParam<std::vector<ExtraElementIDName>>(
      "id_name", "List of extra element ID names by which to separate integral(s).");
  params.addParam<bool>("average", false, "Whether or not to compute volume average");
  MooseEnum mode("atomic reduction", "atomic");
  params.addParam<MooseEnum>("calculation_mode",
                             mode,
                             "Whether to use atomic addition or reduction for parallel summation");
  params.addClassDescription("Integrates or averages variables based on extra element IDs");
  return params;
}

KokkosExtraIDIntegralVectorPostprocessor::KokkosExtraIDIntegralVectorPostprocessor(
    const InputParameters & parameters)
  : ElementVectorPostprocessor(parameters),
    _mesh(_fe_problem.mesh()),
    _average(getParam<bool>("average")),
    _mode(getParam<MooseEnum>("calculation_mode")),
    _nvar(isParamValid("variable") ? coupledComponents("variable") : 0),
    _nprop(isParamValid("mat_prop") ? getParam<std::vector<MaterialPropertyName>>("mat_prop").size()
                                    : 0),
    _prop_names(isParamValid("mat_prop") ? getParam<std::vector<MaterialPropertyName>>("mat_prop")
                                         : std::vector<MaterialPropertyName>()),
    _extra_id(getParam<std::vector<ExtraElementIDName>>("id_name")),
    _n_extra_id(_extra_id.size())
{
  if (!_nvar && !_nprop)
    mooseError("Neither 'variable' nor 'mat_prop' was specified.");

  if (_nvar + _nprop > _cache_size)
    mooseError("Cannot have more than ",
               _cache_size,
               " variables and material properties at the same time.");

  // create map of element ids to parsed vpp ids
  _unique_vpp_id_map =
      MooseMeshUtils::getExtraIDUniqueCombinationMap(_mesh.getMesh(), blockIDs(), _extra_id);

  // set up variable vector containing parsed extra ids
  for (unsigned int i = 0; i < _n_extra_id; ++i)
  {
    const auto id_type = _extra_id[i];
    auto & p = declareVector("Level-" + std::to_string(i) + "-" + id_type);
    // collect local map of local vpp id to extra id
    std::map<dof_id_type, dof_id_type> extra_ids;
    for (const auto elem : _mesh.getMesh().active_local_element_ptr_range())
    {
      if (!hasBlocks(elem->subdomain_id()))
        continue;
      auto vpp_id = libmesh_map_find(_unique_vpp_id_map, elem->id());
      if (extra_ids.find(vpp_id) == extra_ids.end())
        extra_ids[vpp_id] = elem->get_extra_integer(getElementIDIndexByName(id_type));
    }
    // create global map of local vpp id to extra id
    comm().set_union(extra_ids);
    p.resize(extra_ids.size());
    for (auto it : extra_ids)
      p[it.first] = it.second;
    _extra_ids.push_back(&p);
  }

  _vector_size = _extra_ids[0]->size();

  std::vector<std::string> vector_names;

  _integrals.create(_nvar + _prop_names.size());
  _props.create(_prop_names.size());

  unsigned int i = 0;

  // declare vectors containing variable integral values
  for (; i < _nvar; ++i)
  {
    vector_names.push_back(getVar("variable", i)->name());
    auto & p = declareVector(vector_names.back());
    p.resize(_vector_size);
    if (_mode == "atomic")
      _integrals[i].createDevice(p.size());
    else
      _integrals[i].init(p.size());
    _integrals[i].aliasHost(p.data());
  }

  if (_nvar)
    _var_values = kokkosCoupledValues("variable");

  // declare vectors containing material property integral values
  for (unsigned int iprop = 0; iprop < _nprop; ++iprop, ++i)
  {
    vector_names.push_back(_prop_names[iprop]);
    _props[iprop] = getKokkosMaterialPropertyByName<Real>(vector_names.back());
    auto & p = declareVector(vector_names.back());
    p.resize(_vector_size);
    if (_mode == "atomic")
      _integrals[i].createDevice(p.size());
    else
      _integrals[i].init(p.size());
    _integrals[i].aliasHost(p.data());
  }

  _integrals.copyToDevice();
  _props.copyToDevice();
}

void
KokkosExtraIDIntegralVectorPostprocessor::initialSetup()
{
  _unique_vpp_ids.create(kokkosMesh().getNumSubdomains());

  for (const auto block : blockIDs())
  {
    const auto sid = kokkosMesh().getContiguousSubdomainID(block);

    _unique_vpp_ids[sid].create(kokkosMesh().getNumSubdomainLocalElements(block));
    _unique_vpp_ids[sid].offset(*kokkosMesh().getSubdomainContiguousElementIDRange(block).begin());

    for (const auto elem : _mesh.getMesh().active_local_subdomain_elements_ptr_range(block))
    {
      const auto eid = kokkosMesh().getContiguousElementID(elem);

      _unique_vpp_ids[sid](eid) = libmesh_map_find(_unique_vpp_id_map, elem->id());
    }

    _unique_vpp_ids[sid].moveToDevice();
  }

  _unique_vpp_ids.copyToDevice();
}

void
KokkosExtraIDIntegralVectorPostprocessor::initialize()
{
  if (_mode == "atomic")
  {
    for (auto & integral : _integrals)
      integral = 0;

    if (_average)
    {
      _volumes.create(_vector_size);
      _volumes = 0;
    }
  }
  else
    allocateReductionBuffer((_integrals.size() + _average) * _vector_size);
}

void
KokkosExtraIDIntegralVectorPostprocessor::compute()
{
  if (_mode == "atomic")
    computeUserObject();
  else
    computeReducer();
}

void
KokkosExtraIDIntegralVectorPostprocessor::finalize()
{
  if (_mode == "atomic")
  {
    for (auto & integral : _integrals)
    {
      integral.copyToHost();

      libmesh_call_mpi(MPI_Allreduce(MPI_IN_PLACE,
                                     integral.data(),
                                     integral.size(),
                                     libMesh::Parallel::StandardType<Real>(),
                                     libMesh::Parallel::OpFunction<Real>::sum(),
                                     comm().get()));
    }

    if (_average)
    {
      _volumes.copyToHost();

      libmesh_call_mpi(MPI_Allreduce(MPI_IN_PLACE,
                                     _volumes.data(),
                                     _volumes.size(),
                                     libMesh::Parallel::StandardType<Real>(),
                                     libMesh::Parallel::OpFunction<Real>::sum(),
                                     comm().get()));

      for (auto & integral : _integrals)
        for (unsigned int i = 0; i < integral.size(); ++i)
          integral[i] /= _volumes[i];
    }
  }
  else
  {
    libmesh_call_mpi(MPI_Allreduce(MPI_IN_PLACE,
                                   _reduction_buffer.data(),
                                   _reduction_buffer.size(),
                                   libMesh::Parallel::StandardType<Real>(),
                                   libMesh::Parallel::OpFunction<Real>::sum(),
                                   comm().get()));

    for (unsigned int i = 0; i < _integrals.size(); ++i)
      for (unsigned int j = 0; j < _vector_size; ++j)
      {
        _integrals[i][j] = _reduction_buffer[j + i * _vector_size];

        if (_average)
          _integrals[i][j] /= _reduction_buffer[j + _integrals.size() * _vector_size];
      }
  }
}
(framework/src/kokkos/vectorpostprocessors/KokkosExtraIDIntegralVectorPostprocessor.K)

User-defined APIs and Virtual Functions

While user objects are intended to embrace user-defined APIs, Kokkos-MOOSE user objects currently require GPU APIs to not rely on virtual dispatch. Namely, you should always retrieve your user objects in their concrete types if you intend to use your own GPU APIs. Using virtual functions on GPU has two prerequisites: enabling the relocatable device code (RDC) option and constructing objects on GPU. The RDC option is currently disabled in Kokkos-MOOSE due to the restrictions imposed by upstream packages (see the discussions on this page), and its resolution is being actively worked on. Even with the RDC option, however, the object vtables are populated with CPU function pointers as all objects in MOOSE are constructed on CPU. As a result, you still cannot call virtual functions of your user objects on GPU unless you directly construct them on GPU (see this page).

In order to realize virtual dispatch with your user objects, therefore, you need to implement a wrapper with virtual functions that can be easily constructed on GPU, and call your own APIs through the wrapper. This wrapper will hold the GPU copy of your user object in its concrete type and the virtual functions that call the corresponding user object functions statically. This approach is implemented in Moose::Kokkos::Function using a registry design pattern and can be found across framework source files such as KokkosFunctionWrapper.h and KokkosFunction.h, but it requires a deep understanding of dynamic polymorphism and GPU backends. Therefore, we plan to explore developing base classes for the wrapper that the users can easily derive from and providing programming guidelines, once the RDC option is in place.

Available Objects

Available Objects

Available Objects

  • Moose App
  • ArrayVariableValueVolumeHistogramCompute histograms of volume fractions binned according to component values of an array variable.
  • CSVReaderConverts columns of a CSV file into vectors of a VectorPostprocessor.
  • CSVReaderVectorPostprocessorConverts columns of a CSV file into vectors of a VectorPostprocessor.
  • CombinedVectorPostprocessorOutputs the values of an arbitrary user-specified set of vectorpostprocessors as a combined vector in the order specified by the user
  • ConstantVectorPostprocessorPopulate constant VectorPostprocessorValue directly from input file.
  • CylindricalAverageCompute a cylindrical average of a variableas a function of radius throughout the simulation domain.
  • EigenvaluesReturns the Eigen values from the nonlinear Eigen system.
  • ElementMaterialSamplerRecords all Real-valued material properties of a material object, or Real-valued material properties of the supplied property names on quadrature points on elements at the indicated execution points.
  • ElementValueSamplerSamples values of variables on elements.
  • ElementVariablesDifferenceMaxComputes the largest difference between two variable fields.
  • ElementsAlongLineOutputs the IDs of every element intersected by a user-defined line
  • ElementsAlongPlaneOutputs the IDs of every element intersected by a user-defined plane
  • ExtraIDIntegralVectorPostprocessorIntegrates or averages variables based on extra element IDs
  • HistogramVectorPostprocessorCompute a histogram for each column of a VectorPostprocessor
  • IntersectionPointsAlongLineGet the intersection points for all of the elements that are intersected by a line.
  • KokkosExtraIDIntegralVectorPostprocessorIntegrates or averages variables based on extra element IDs
  • LeastSquaresFitPerforms a polynomial least squares fit on the data contained in another VectorPostprocessor
  • LeastSquaresFitHistoryPerforms a polynomial least squares fit on the data contained in another VectorPostprocessor and stores the full time history of the coefficients
  • LineFunctionSamplerSample one or more functions along a line.
  • LineMaterialRealSamplerSamples real-valued material properties for all quadrature points in all elements that are intersected by a specified line
  • LineValueSamplerSamples variable(s) along a specified line
  • MFEMEigenvaluesPostprocessorRetrieves the eigenvalues from an eigensolve for exporting.
  • MFEMLineValueSamplerSample an MFEM variable along a specified line.
  • MFEMPointValueSamplerSample an MFEM variable at specific points.
  • MaterialVectorPostprocessorRecords all Real-valued material properties of a material object, or Real-valued material properties of the supplied property names on quadrature points on elements at the indicated execution points.
  • MeshDivisionFunctorReductionVectorPostprocessorPerform reductions on functors based on a per-mesh-division basis
  • NearestPointIntegralVariablePostprocessorCompute element variable integrals for nearest-point based subdomains
  • NodalValueSamplerSamples values of nodal variable(s).
  • PointValueSamplerSample a variable at specific points.
  • PositionsFunctorValueSamplerSample one or more functors at points specified by a Positions object.
  • SideValueSamplerSample variable(s) along a sideset, internal or external.
  • SidesetInfoVectorPostprocessorThis VectorPostprocessor collects meta data for provided sidesets.
  • SpatialUserObjectVectorPostprocessorOutputs the values of a spatial user object in the order of the specified spatial points
  • SphericalAverageCompute a spherical average of a variable as a function of radius throughout the simulation domain.
  • VariableValueVolumeHistogramCompute a histogram of volume fractions binned according to variable values.
  • VectorMemoryUsageGet memory stats for all ranks in the simulation
  • VectorOfPostprocessorsOutputs the values of an arbitrary user-specified set of postprocessors as a vector in the order specified by the user
  • VolumeHistogramCompute a histogram of volume fractions binned according to variable values.
  • WorkBalanceComputes several metrics for workload balance per processor
  • Ray Tracing App
  • PerProcessorRayTracingResultsVectorPostprocessorAccumulates ray tracing results (information about the trace) on a per-processor basis.
  • Navier Stokes App
  • WaveSpeedVPPExtracts wave speeds from HLLC userobject for a given face
  • Solid Mechanics App
  • ADInteractionIntegralComputes the interaction integral, which is used to compute various fracture mechanics parameters at a crack tip, including KI, KII, KIII, and the T stress.
  • AverageSectionValueSamplerCompute the section's variable average in three-dimensions given a user-defined definition of the cross section.
  • BlockOrientationFromUserObjectOutput the Euler angle for each block computed from average of quaternions.
  • CrackFrontNonlocalScalarMaterialComputes the average material at points provided by the crack_front_definition vectorpostprocessor.
  • CrackFrontNonlocalStressComputes the average stress normal to the crack face.
  • InteractionIntegralComputes the interaction integral, which is used to compute various fracture mechanics parameters at a crack tip, including KI, KII, KIII, and the T stress.
  • JIntegralComputes the J-Integral, a measure of the strain energy release rate at a crack tip, which can be used as a criterion for fracture growth. It can, alternatively, compute the C(t) integral
  • LineMaterialRankTwoSamplerAccess a component of a RankTwoTensor
  • LineMaterialRankTwoScalarSamplerCompute a scalar property of a RankTwoTensor
  • MixedModeEquivalentKComputes the mixed-mode stress intensity factor given the , , and stress intensity factors
  • Phase Field App
  • EulerAngleUpdaterCheckProvide updated Euler angles after rigid body rotation of the grains.
  • FeatureVolumeVectorPostprocessorThis object is designed to pull information from the data structures of a "FeatureFloodCount" or derived object (e.g. individual feature volumes)
  • GrainForcesPostprocessorOutputs the values from GrainForcesPostprocessor
  • GrainTextureVectorPostprocessorGives out info on the grain boundary properties
  • Optimization App
  • AdjointStrainSymmetricStressGradInnerProductThis component is designed to compute the gradient of the objective function concerning specific properties. It achieves this by computing the inner product of the property derivative obtained a material property and the strain resulting from the forward simulation.
  • ElementOptimizationDiffusionCoefFunctionInnerProductCompute the gradient for material inversion by taking the inner product of gradients of the forward and adjoint variables with material gradient
  • ElementOptimizationReactionFunctionInnerProductCompute the gradient for reaction material inversion by taking the inner product of the forward and adjoint variables multiplied by the derivative of the optimization function with respect to the controllable parameters.
  • ElementOptimizationSourceFunctionInnerProductComputes the inner product of variable with parameterized source function for optimization gradient computation.
  • SideOptimizationNeumannFunctionInnerProductComputes the inner product of variable with parameterized Neumann function for optimization gradient computation.
  • Stochastic Tools App
  • GaussianProcessDataTool for extracting hyperparameter data from gaussian process user object and storing in VectorPostprocessor vectors.
  • SamplerDataTool for extracting Sampler object data and storing in VectorPostprocessor vectors.
  • SobolStatisticsCompute SOBOL statistics values of a given VectorPostprocessor objects and vectors.
  • StatisticsCompute statistical values of a given VectorPostprocessor objects and vectors.
  • StochasticResultsStorage container for stochastic simulation results coming from a Postprocessor.
  • Thermal Hydraulics App
  • ADSampler1DRealSamples material properties at all quadrature points in mesh block(s)
  • NumericalFlux3EqnInternalValuesComputes internal fluxes for FlowChannel1Phase.
  • Sampler1DRealSamples material properties at all quadrature points in mesh block(s)
  • Sampler1DVectorSamples a single component of array material properties at all quadrature points in mesh block(s)
  • Heat Transfer App
  • SurfaceRadiationVectorPostprocessorVectorPostprocessor for accessing information stored in surface radiation user object
  • ViewFactorVectorPostprocessorVectorPostprocessor for accessing view factors from GrayLambertSurfaceRadiationBase UO
  • ViewfactorVectorPostprocessorVectorPostprocessor for accessing view factors from GrayLambertSurfaceRadiationBase UO

Available Objects

  • Moose App
  • ADElementExtremeMaterialPropertyReporterDetermines the location of the minimum or maximum value of a material property over a volume, and provides its coordinates and optionally other requested data at that location.
  • AccumulateReporterReporter which accumulates the value of a inputted reporter value over time into a vector reporter value of the same type.
  • ConstantReporterReporter with constant values to be accessed by other objects, can be modified using transfers.
  • ElementExtremeMaterialPropertyReporterDetermines the location of the minimum or maximum value of a material property over a volume, and provides its coordinates and optionally other requested data at that location.
  • ElementVariableStatisticsElement reporter to get statistics for a coupled variable. This can be transfered to other apps.
  • ExtraIDIntegralReporterThis ExtraIDIntegralReporter source code is to integrate variables based on parsed extra IDs based on reporter system.
  • IterationInfoReport the time and iteration information for the simulation.
  • KokkosElementVariableStatisticsElement reporter to get statistics for a coupled variable. This can be transfered to other apps.
  • KokkosNodalVariableStatisticsNodal reporter to get statistics for a coupled variable. This can be transfered to other apps.
  • LibtorchArtificialNeuralNetParametersOutputs the parameters of a LibtorchArtificialNeuralNetwork within a LibtorchNeuralNetControl.
  • MeshInfoReport mesh information, such as the number of elements, nodes, and degrees of freedom.
  • MeshMetaDataReporterReports the mesh meta data.
  • MortarSegmentMeshReporterReports mortar segment mesh statistics (element counts and volume statistics) for all mortar interfaces. One entry per primary-secondary subdomain pair is appended to each output vector.
  • NodalVariableStatisticsNodal reporter to get statistics for a coupled variable. This can be transfered to other apps.
  • ParsedScalarReporterApplies parsed functions to scalar entries held in reporters.
  • ParsedVectorRealReductionReporterUse a parsed function to iterate through a vector and reduce it to a scalar.
  • ParsedVectorReporterApply parsed functions to vector entries held in reporters.
  • ParsedVectorVectorRealReductionReporterUse a parsed function to iterate through a rows of a vector of vector and reduce it to a vector.
  • PerfGraphReporterReports the full performance graph from the PerfGraph.
  • RestartableDataReporterReports restartable data and restartable meta data.
  • SolutionInvalidityReporterReports the Summary Table of Solution Invalid Counts.
  • XFEMApp
  • ParisLawThis reporter computes the crack growth increment at all active crack front points in the CrackMeshCut3DUserObject for fatigue crack growth based on the Paris Law. Data for crack growth rates in this reporter are stored in the same order as in the fracture integral VectorPostprocessors.
  • StressCorrosionCrackingExponentialThis reporter computes the crack growth increment at all active crack front points in the CrackMeshCut3DUserObject for stress corrosion cracking fit to an exponential function. Crack growth rates computed by this reporter are stored in the same order as in the fracture integral VectorPostprocessors.
  • Optimization App
  • OptimizationDataReporter to hold measurement and simulation data for optimization problems
  • OptimizationInfoReports Optimization Output
  • Stochastic Tools App
  • ActiveLearningGPDecisionEvaluates a GP surrogate model, determines its prediction quality, launches full model if GP prediction is inadequate, and retrains GP.
  • AdaptiveImportanceStatsReporter to compute statistics corresponding to the AdaptiveImportanceSampler.
  • AdaptiveMonteCarloDecisionGeneric reporter which decides whether or not to accept a proposed sample in Adaptive Monte Carlo type of algorithms.
  • AffineInvariantDifferentialDecisionPerform decision making for Affine Invariant differential MCMC.
  • AffineInvariantStretchDecisionPerform decision making for Affine Invariant stretch MCMC.
  • BayesianActiveLearnerA reporter to support parallel active learning for Bayesian UQ tasks.
  • BiFidelityActiveLearningGPDecisionPerform active learning decision making in bi-fidelity modeling.
  • ConditionalSampleReporterEvaluates parsed function to determine if sample needs to be evaluated, otherwise data is set to a default value.
  • CrossValidationScoresTool for extracting cross-validation scores and storing them in a reporter for output.
  • DRLControlNeuralNetParametersOutputs the parameters of a LibtorchArtificialNeuralNetwork within a LibtorchDRLControlTrainer.
  • DRLRewardReporterReporter containing the reward values of a DRL controller trainer.
  • DirectPerturbationReporterCompute local sensitivities using the direct perturbation method.
  • EvaluateSurrogateTool for sampling surrogate models.
  • GenericActiveLearnerA generic reporter to support parallel active learning: re-trains GP and picks the next best batch.
  • IndependentMHDecisionPerform decision making for independent Metropolis-Hastings MCMC.
  • MappingReporterA reporter which can map full solution fields to a latent space for given variables.
  • MorrisReporterCompute global sensitivities using the Morris method.
  • PMCMCDecisionGeneric reporter which decides whether or not to accept a proposed sample in parallel Markov chain Monte Carlo type of algorithms.
  • ParallelSolutionStorageParallel container to store serialized solution fields from simulations on sub-applications.
  • PolynomialChaosReporterTool for extracting data from PolynomialChaos surrogates and computing statistics.
  • SingularTripletReporterTool for accessing and outputting the singular triplets of a singular value decomposition in PODMapping.
  • SobolReporterCompute SOBOL statistics values of a given VectorPostprocessor or Reporter objects and vectors.
  • SolutionContainerClass responsible for collecting distributed solution vectors into a container. We append a new distributed solution vector (containing all variables) at every execution.
  • StatisticsReporterCompute statistical values of a given VectorPostprocessor objects and vectors.
  • StochasticMatrixTool for extracting Sampler object data and storing data from stochastic simulations.
  • StochasticReporterStorage container for stochastic simulation results coming from Reporters.