28#ifndef EWOMS_P1FE_GRADIENT_CALCULATOR_HH
29#define EWOMS_P1FE_GRADIENT_CALCULATOR_HH
31#include <dune/common/fvector.hh>
33#include <dune/geometry/type.hh>
35#include <dune/common/version.hh>
39#if HAVE_DUNE_LOCALFUNCTIONS
40#include <dune/localfunctions/lagrange/pqkfactory.hh>
60template<
class TypeTag>
69 enum { dim = GridView::dimension };
74 enum { maxDof = (2 << dim) };
75 enum { maxFap = maxDof };
77 using CoordScalar =
typename GridView::ctype;
78 using DimVector = Dune::FieldVector<Scalar, dim>;
80#if HAVE_DUNE_LOCALFUNCTIONS
81 using LocalFiniteElementCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
82 using LocalFiniteElement =
typename LocalFiniteElementCache::FiniteElementType;
83 using LocalBasisTraits =
typename LocalFiniteElement::Traits::LocalBasisType::Traits;
84 using ShapeJacobian =
typename LocalBasisTraits::JacobianType;
94 template <
bool prepareValues = true,
bool prepareGradients = true>
95 void prepare([[maybe_unused]]
const ElementContext& elemCtx,
96 [[maybe_unused]]
unsigned timeIdx)
98 if constexpr (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
99#if !HAVE_DUNE_LOCALFUNCTIONS
101 throw std::logic_error(
"The dune-localfunctions module is required in order to use"
102 " finite element gradients");
104 const auto& stencil = elemCtx.stencil(timeIdx);
106 const LocalFiniteElement& localFE = feCache_.get(elemCtx.element().type());
107 localFiniteElement_ = &localFE;
110 for (
unsigned faceIdx = 0; faceIdx < stencil.numInteriorFaces(); ++faceIdx) {
111 const auto& localFacePos = stencil.interiorFace(faceIdx).localPos();
116 localFE.localBasis().evaluateFunction(localFacePos, p1Value_[faceIdx]);
119 if (prepareGradients) {
121 std::vector<ShapeJacobian> localGradient;
122 localFE.localBasis().evaluateJacobian(localFacePos, localGradient);
127 const auto& geom = elemCtx.element().geometry();
128 const auto& jacInvT =
129 geom.jacobianInverseTransposed(localFacePos);
131 std::size_t numVertices = elemCtx.numDof(timeIdx);
132 for (
unsigned vertIdx = 0; vertIdx < numVertices; vertIdx++) {
133 jacInvT.mv(localGradient[vertIdx][0],
134 p1Gradient_[faceIdx][vertIdx]);
141 ParentType::template prepare<prepareValues, prepareGradients>(elemCtx, timeIdx);
156 template <
class QuantityCallback>
158 [[maybe_unused]]
unsigned fapIdx,
159 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
160 -> std::remove_reference_t<typename QuantityCallback::ResultType>
162 if constexpr (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
163#if !HAVE_DUNE_LOCALFUNCTIONS
165 throw std::logic_error(
"The dune-localfunctions module is required in order to use"
166 " finite element gradients");
168 using QuantityConstType = std::remove_reference_t<typename QuantityCallback::ResultType>;
169 using QuantityType = std::remove_const_t<QuantityConstType>;
170 using Toolbox = MathToolbox<QuantityType>;
174 QuantityType value(0.0);
175 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
176 if (std::is_same_v<QuantityType, Scalar> ||
177 elemCtx.focusDofIndex() == vertIdx)
179 value += quantityCallback(vertIdx)*p1Value_[fapIdx][vertIdx];
182 value += Toolbox::value(quantityCallback(vertIdx))*p1Value_[fapIdx][vertIdx];
205 template <
class QuantityCallback>
207 [[maybe_unused]]
unsigned fapIdx,
208 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
209 -> std::remove_reference_t<typename QuantityCallback::ResultType>
211 if constexpr (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
212#if !HAVE_DUNE_LOCALFUNCTIONS
214 throw std::logic_error(
"The dune-localfunctions module is required in order to use"
215 " finite element gradients");
217 using QuantityConstType = std::remove_reference_t<typename QuantityCallback::ResultType>;
218 using QuantityType = std::remove_const_t<QuantityConstType>;
220 using RawFieldType =
decltype(std::declval<QuantityType>()[0]);
221 using FieldType = std::remove_const_t<std::remove_reference_t<RawFieldType>>;
223 using Toolbox = MathToolbox<FieldType>;
227 QuantityType value(0.0);
228 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
229 if (std::is_same_v<QuantityType, Scalar> ||
230 elemCtx.focusDofIndex() == vertIdx)
232 const auto& tmp = quantityCallback(vertIdx);
233 for (
unsigned k = 0; k < tmp.size(); ++k) {
234 value[k] += tmp[k]*p1Value_[fapIdx][vertIdx];
238 const auto& tmp = quantityCallback(vertIdx);
239 for (
unsigned k = 0; k < tmp.size(); ++k) {
240 value[k] += Toolbox::value(tmp[k])*p1Value_[fapIdx][vertIdx];
264 template <
class QuantityCallback,
class EvalDimVector>
266 [[maybe_unused]]
const ElementContext& elemCtx,
267 [[maybe_unused]]
unsigned fapIdx,
268 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
270 if constexpr (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
271#if !HAVE_DUNE_LOCALFUNCTIONS
273 throw std::logic_error(
"The dune-localfunctions module is required in order to use"
274 " finite element gradients");
276 using QuantityConstType = std::remove_reference_t<typename QuantityCallback::ResultType>;
277 using QuantityType = std::remove_const_t<QuantityConstType>;
282 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
283 if (std::is_same_v<QuantityType, Scalar> ||
284 elemCtx.focusDofIndex() == vertIdx)
286 const auto& dofVal = quantityCallback(vertIdx);
287 const auto& tmp = p1Gradient_[fapIdx][vertIdx];
288 for (
int dimIdx = 0; dimIdx < dim; ++dimIdx) {
289 quantityGrad[dimIdx] += dofVal * tmp[dimIdx];
293 const auto& dofVal = quantityCallback(vertIdx);
294 const auto& tmp = p1Gradient_[fapIdx][vertIdx];
295 for (
int dimIdx = 0; dimIdx < dim; ++dimIdx) {
296 quantityGrad[dimIdx] += scalarValue(dofVal) * tmp[dimIdx];
321 template <
class QuantityCallback>
324 const QuantityCallback& quantityCallback)
342 template <
class QuantityCallback,
class EvalDimVector>
344 const ElementContext& elemCtx,
346 const QuantityCallback& quantityCallback)
const
349#if HAVE_DUNE_LOCALFUNCTIONS
350 static LocalFiniteElementCache& localFiniteElementCache()
355#if HAVE_DUNE_LOCALFUNCTIONS
356 static LocalFiniteElementCache feCache_;
358 const LocalFiniteElement* localFiniteElement_{
nullptr};
359 std::array<std::vector<Dune::FieldVector<Scalar, 1>>, maxFap> p1Value_{};
360 std::array<std::array<DimVector, maxDof>, maxFap>{};
364#if HAVE_DUNE_LOCALFUNCTIONS
365template<
class TypeTag>
366typename P1FeGradientCalculator<TypeTag>::LocalFiniteElementCache
367P1FeGradientCalculator<TypeTag>::feCache_;
This class calculates gradients of arbitrary quantities at flux integration points using the two-poin...
Definition: fvbasegradientcalculator.hh:52
auto calculateScalarValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const -> std::remove_reference_t< decltype(quantityCallback.operator()(0))>
Calculates the value of an arbitrary scalar quantity at any interior flux approximation point.
Definition: fvbasegradientcalculator.hh:100
void calculateBoundaryGradient(EvalDimVector &quantityGrad, const ElementContext &elemCtx, unsigned faceIdx, const QuantityCallback &quantityCallback) const
Calculates the gradient of an arbitrary quantity at any flux approximation point on the boundary.
Definition: fvbasegradientcalculator.hh:292
auto calculateVectorValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const -> std::remove_reference_t< decltype(quantityCallback.operator()(0))>
Calculates the value of an arbitrary vectorial quantity at any interior flux approximation point.
Definition: fvbasegradientcalculator.hh:149
void calculateGradient(EvalDimVector &quantityGrad, const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const
Calculates the gradient of an arbitrary quantity at any flux approximation point.
Definition: fvbasegradientcalculator.hh:214
auto calculateBoundaryValue(const ElementContext &, unsigned, const QuantityCallback &quantityCallback) -> decltype(quantityCallback.boundaryValue())
Calculates the value of an arbitrary quantity at any flux approximation point on the grid boundary.
Definition: fvbasegradientcalculator.hh:271
This class calculates gradients of arbitrary quantities at flux integration points using first order ...
Definition: p1fegradientcalculator.hh:62
auto calculateVectorValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const -> std::remove_reference_t< typename QuantityCallback::ResultType >
Calculates the value of an arbitrary quantity at any interior flux approximation point.
Definition: p1fegradientcalculator.hh:206
void calculateBoundaryGradient(EvalDimVector &quantityGrad, const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const
Calculates the gradient of an arbitrary quantity at any flux approximation point on the boundary.
Definition: p1fegradientcalculator.hh:343
auto calculateScalarValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const -> std::remove_reference_t< typename QuantityCallback::ResultType >
Calculates the value of an arbitrary quantity at any interior flux approximation point.
Definition: p1fegradientcalculator.hh:157
auto calculateBoundaryValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) -> decltype(ParentType::calculateBoundaryValue(elemCtx, fapIdx, quantityCallback))
Calculates the value of an arbitrary quantity at any flux approximation point on the grid boundary.
Definition: p1fegradientcalculator.hh:322
void prepare(const ElementContext &elemCtx, unsigned timeIdx)
Precomputes the common values to calculate gradients and values of quantities at any flux approximati...
Definition: p1fegradientcalculator.hh:95
void calculateGradient(EvalDimVector &quantityGrad, const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const
Calculates the gradient of an arbitrary quantity at any flux approximation point.
Definition: p1fegradientcalculator.hh:265
Definition: blackoilboundaryratevector.hh:39
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
Declares the basic properties used by the common infrastructure of the vertex-centered finite volume ...