Skip to content

Commit

Permalink
Generalizations for Moose functor for std::array functors
Browse files Browse the repository at this point in the history
  • Loading branch information
lindsayad committed Apr 13, 2022
1 parent 0916cbf commit 622a55d
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 9 deletions.
76 changes: 76 additions & 0 deletions framework/include/utils/ArrayComponentFunctor.h
@@ -0,0 +1,76 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#pragma once

#include "MooseFunctor.h"

/**
* This is essentially a forwarding functor that forwards the spatial and temporal evaluation
* arguments to the parent array functor and then returns the result indexed at a given component.
*/
template <typename T, typename ArrayTypeFunctor>
class ArrayComponentFunctor : public Moose::FunctorBase<T>
{
public:
using typename Moose::FunctorBase<T>::ValueType;
using typename Moose::FunctorBase<T>::GradientType;
using typename Moose::FunctorBase<T>::DotType;

ArrayComponentFunctor(const ArrayTypeFunctor & array, const unsigned int component)
: _array(array), _component(component)
{
}

bool isExtrapolatedBoundaryFace(const FaceInfo & fi) const override
{
return _array.isExtrapolatedBoundaryFace(fi);
}

private:
/// The parent array functor
const ArrayTypeFunctor & _array;

/// The component at which we'll index the parent array functor evaluation result
const unsigned int _component;

ValueType evaluate(const Moose::ElemArg & elem, const unsigned int state) const override final
{
return _array(elem, state)[_component];
}

ValueType evaluate(const Moose::ElemFromFaceArg & elem_from_face,
const unsigned int state) const override final
{
return _array(elem_from_face, state)[_component];
}

ValueType evaluate(const Moose::FaceArg & face, const unsigned int state) const override final
{
return _array(face, state)[_component];
}

ValueType evaluate(const Moose::SingleSidedFaceArg & face,
const unsigned int state) const override final
{
return _array(face, state)[_component];
}

ValueType evaluate(const Moose::ElemQpArg & elem_qp,
const unsigned int state) const override final
{
return _array(elem_qp, state)[_component];
}

ValueType evaluate(const Moose::ElemSideQpArg & elem_side_qp,
const unsigned int state) const override final
{
return _array(elem_side_qp, state)[_component];
}
};
38 changes: 30 additions & 8 deletions framework/include/utils/GreenGaussGradient.h
Expand Up @@ -14,6 +14,7 @@
#include "FVUtils.h"
#include "MooseMeshUtils.h"
#include "VectorComponentFunctor.h"
#include "ArrayComponentFunctor.h"
#include "libmesh/elem.h"

namespace Moose
Expand Down Expand Up @@ -311,15 +312,14 @@ TensorValue<T>
greenGaussGradient(const ElemArg & elem_arg,
const Moose::FunctorBase<VectorValue<T>> & functor,
const bool two_term_boundary_expansion,
const MooseMesh & mesh,
std::unordered_map<const FaceInfo *, T> * const face_to_value_cache = nullptr)
const MooseMesh & mesh)
{
TensorValue<T> ret;
for (const auto i : make_range(unsigned(LIBMESH_DIM)))
{
VectorComponentFunctor<T> scalar_functor(functor, i);
const auto row_gradient = greenGaussGradient(
elem_arg, scalar_functor, two_term_boundary_expansion, mesh, face_to_value_cache);
const auto row_gradient =
greenGaussGradient(elem_arg, scalar_functor, two_term_boundary_expansion, mesh);
for (const auto j : make_range(unsigned(LIBMESH_DIM)))
ret(i, j) = row_gradient(j);
}
Expand Down Expand Up @@ -353,11 +353,33 @@ typename Moose::FunctorBase<std::vector<T>>::GradientType
greenGaussGradient(const ElemArg &,
const Moose::FunctorBase<std::vector<T>> &,
const bool,
const MooseMesh &,
std::unordered_map<const FaceInfo *, std::vector<T>> * const = nullptr)
const MooseMesh &)
{
mooseError("It doesn't make any sense to call this function. There is no size to a vector "
"functor. I suppose we could call the value type overload and get the size from the "
"returned vector size, but that's not very efficient. If you want us to do that "
"though, please contact a MOOSE developer");
}

template <typename T, std::size_t N>
typename Moose::FunctorBase<std::array<T, N>>::GradientType
greenGaussGradient(const ElemArg & elem_arg,
const Moose::FunctorBase<std::array<T, N>> & functor,
const bool two_term_boundary_expansion,
const MooseMesh & mesh)
{
mooseError(
"It doesn't make any sense to call this function. There is no size to a vector functor.");
typedef typename Moose::FunctorBase<std::array<T, N>>::GradientType GradientType;
GradientType ret;
for (const auto i : make_range(N))
{
// Note that this can be very inefficient. Within the scalar greenGaussGradient routine we're
// going to do value type evaluations of the array functor from scalar_functor and we will be
// discarding all the value type evaluations other than the one corresponding to i
ArrayComponentFunctor<T, FunctorBase<std::array<T, N>>> scalar_functor(functor, i);
ret[i] = greenGaussGradient(elem_arg, scalar_functor, two_term_boundary_expansion, mesh);
}

return ret;
}
}
}
28 changes: 28 additions & 0 deletions framework/include/utils/MathFVUtils.h
Expand Up @@ -570,6 +570,34 @@ interpolate(const Limiter & limiter,
return ret;
}

/**
* std::array overload
*/
template <typename Limiter, typename ValueType, typename GradientType, std::size_t N>
std::array<ValueType, N>
interpolate(const Limiter & limiter,
const std::array<ValueType, N> & phi_upwind,
const std::array<ValueType, N> & phi_downwind,
const std::array<GradientType, N> * const grad_phi_upwind,
const FaceInfo & fi,
const bool fi_elem_is_upwind)
{
mooseAssert(limiter.constant() || grad_phi_upwind,
"Non-null gradient only supported for constant limiters.");

std::array<ValueType, N> ret;
const GradientType * gradient = nullptr;
for (const auto i : make_range(N))
{
if (grad_phi_upwind)
gradient = &(*grad_phi_upwind)[i];

ret[i] = interpolate(limiter, phi_upwind[i], phi_downwind[i], gradient, fi, fi_elem_is_upwind);
}

return ret;
}

/**
* Return whether the supplied face is on a boundary of the \p object's execution
*/
Expand Down
2 changes: 1 addition & 1 deletion framework/include/utils/PiecewiseByBlockLambdaFunctor.h
Expand Up @@ -234,7 +234,7 @@ PiecewiseByBlockLambdaFunctor<T>::evaluate(const Moose::FaceArg & face, unsigned

mooseAssert(face.fi,
"We must have a non-null face_info in order to prepare our ElemFromFace tuples");
static const GradientType example_gradient(0);
static const GradientType example_gradient;

switch (face.limiter_type)
{
Expand Down

0 comments on commit 622a55d

Please sign in to comment.