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;
95 template <
bool prepareValues = true,
bool prepareGradients = true>
96 void prepare([[maybe_unused]]
const ElementContext& elemCtx,
97 [[maybe_unused]]
unsigned timeIdx)
99 if constexpr (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
100#if !HAVE_DUNE_LOCALFUNCTIONS
102 throw std::logic_error(
"The dune-localfunctions module is required in order to use"
103 " finite element gradients");
105 const auto& stencil = elemCtx.stencil(timeIdx);
107 const LocalFiniteElement& localFE = feCache_.get(elemCtx.element().type());
108 localFiniteElement_ = &localFE;
111 for (
unsigned faceIdx = 0; faceIdx < stencil.numInteriorFaces(); ++faceIdx) {
112 const auto& localFacePos = stencil.interiorFace(faceIdx).localPos();
117 localFE.localBasis().evaluateFunction(localFacePos, p1Value_[faceIdx]);
120 if (prepareGradients) {
122 std::vector<ShapeJacobian> localGradient;
123 localFE.localBasis().evaluateJacobian(localFacePos, localGradient);
128 const auto& geom = elemCtx.element().geometry();
129 const auto& jacInvT =
130 geom.jacobianInverseTransposed(localFacePos);
132 std::size_t numVertices = elemCtx.numDof(timeIdx);
133 for (
unsigned vertIdx = 0; vertIdx < numVertices; vertIdx++) {
134 jacInvT.mv(localGradient[vertIdx][0],
135 p1Gradient_[faceIdx][vertIdx]);
142 ParentType::template prepare<prepareValues, prepareGradients>(elemCtx, timeIdx);
157 template <
class QuantityCallback>
159 [[maybe_unused]]
unsigned fapIdx,
160 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
161 -> std::remove_reference_t<typename QuantityCallback::ResultType>
163 if constexpr (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
164#if !HAVE_DUNE_LOCALFUNCTIONS
166 throw std::logic_error(
"The dune-localfunctions module is required in order to use"
167 " finite element gradients");
169 using QuantityConstType = std::remove_reference_t<typename QuantityCallback::ResultType>;
170 using QuantityType = std::remove_const_t<QuantityConstType>;
171 using Toolbox = MathToolbox<QuantityType>;
175 QuantityType value(0.0);
176 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
177 if (std::is_same_v<QuantityType, Scalar> ||
178 elemCtx.focusDofIndex() == vertIdx)
180 value += quantityCallback(vertIdx)*p1Value_[fapIdx][vertIdx];
183 value += Toolbox::value(quantityCallback(vertIdx))*p1Value_[fapIdx][vertIdx];
206 template <
class QuantityCallback>
208 [[maybe_unused]]
unsigned fapIdx,
209 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
210 -> std::remove_reference_t<typename QuantityCallback::ResultType>
212 if constexpr (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
213#if !HAVE_DUNE_LOCALFUNCTIONS
215 throw std::logic_error(
"The dune-localfunctions module is required in order to use"
216 " finite element gradients");
218 using QuantityConstType = std::remove_reference_t<typename QuantityCallback::ResultType>;
219 using QuantityType = std::remove_const_t<QuantityConstType>;
221 using RawFieldType =
decltype(std::declval<QuantityType>()[0]);
222 using FieldType = std::remove_const_t<std::remove_reference_t<RawFieldType>>;
224 using Toolbox = MathToolbox<FieldType>;
228 QuantityType value(0.0);
229 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
230 if (std::is_same_v<QuantityType, Scalar> ||
231 elemCtx.focusDofIndex() == vertIdx)
233 const auto& tmp = quantityCallback(vertIdx);
234 for (
unsigned k = 0; k < tmp.size(); ++k) {
235 value[k] += tmp[k]*p1Value_[fapIdx][vertIdx];
239 const auto& tmp = quantityCallback(vertIdx);
240 for (
unsigned k = 0; k < tmp.size(); ++k) {
241 value[k] += Toolbox::value(tmp[k])*p1Value_[fapIdx][vertIdx];
266 template <
class QuantityCallback,
class EvalDimVector>
268 [[maybe_unused]]
const ElementContext& elemCtx,
269 [[maybe_unused]]
unsigned fapIdx,
270 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
272 if constexpr (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
273#if !HAVE_DUNE_LOCALFUNCTIONS
275 throw std::logic_error(
"The dune-localfunctions module is required in order to use"
276 " finite element gradients");
278 using QuantityConstType = std::remove_reference_t<typename QuantityCallback::ResultType>;
279 using QuantityType = std::remove_const_t<QuantityConstType>;
284 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
285 if (std::is_same_v<QuantityType, Scalar> ||
286 elemCtx.focusDofIndex() == vertIdx)
288 const auto& dofVal = quantityCallback(vertIdx);
289 const auto& tmp = p1Gradient_[fapIdx][vertIdx];
290 for (
int dimIdx = 0; dimIdx < dim; ++dimIdx) {
291 quantityGrad[dimIdx] += dofVal * tmp[dimIdx];
295 const auto& dofVal = quantityCallback(vertIdx);
296 const auto& tmp = p1Gradient_[fapIdx][vertIdx];
297 for (
int dimIdx = 0; dimIdx < dim; ++dimIdx) {
298 quantityGrad[dimIdx] += scalarValue(dofVal) * tmp[dimIdx];
323 template <
class QuantityCallback>
326 const QuantityCallback& quantityCallback)
345 template <
class QuantityCallback,
class EvalDimVector>
347 const ElementContext& elemCtx,
349 const QuantityCallback& quantityCallback)
const
352#if HAVE_DUNE_LOCALFUNCTIONS
353 static LocalFiniteElementCache& localFiniteElementCache()
358#if HAVE_DUNE_LOCALFUNCTIONS
359 static LocalFiniteElementCache feCache_;
361 const LocalFiniteElement* localFiniteElement_{
nullptr};
362 std::array<std::vector<Dune::FieldVector<Scalar, 1>>, maxFap> p1Value_{};
363 std::array<std::array<DimVector, maxDof>, maxFap>{};
367#if HAVE_DUNE_LOCALFUNCTIONS
368template<
class TypeTag>
369typename P1FeGradientCalculator<TypeTag>::LocalFiniteElementCache
370P1FeGradientCalculator<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:294
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:215
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:272
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:207
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:346
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:158
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:324
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:96
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:267
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 ...