28#ifndef EWOMS_P1FE_GRADIENT_CALCULATOR_HH
29#define EWOMS_P1FE_GRADIENT_CALCULATOR_HH
35#include <dune/common/fvector.hh>
36#include <dune/common/version.hh>
38#include <dune/geometry/type.hh>
40#if HAVE_DUNE_LOCALFUNCTIONS
41#include <dune/localfunctions/lagrange/pqkfactory.hh>
44#include <dune/common/fvector.hh>
58template<
class TypeTag>
67 enum { dim = GridView::dimension };
72 enum { maxDof = (2 << dim) };
73 enum { maxFap = maxDof };
75 using CoordScalar =
typename GridView::ctype;
76 using DimVector = Dune::FieldVector<Scalar, dim>;
78#if HAVE_DUNE_LOCALFUNCTIONS
79 using LocalFiniteElementCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
80 using LocalFiniteElement =
typename LocalFiniteElementCache::FiniteElementType;
81 using LocalBasisTraits =
typename LocalFiniteElement::Traits::LocalBasisType::Traits;
82 using ShapeJacobian =
typename LocalBasisTraits::JacobianType;
92 template <
bool prepareValues = true,
bool prepareGradients = true>
93 void prepare([[maybe_unused]]
const ElementContext& elemCtx,
94 [[maybe_unused]]
unsigned timeIdx)
96 if (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
97#if !HAVE_DUNE_LOCALFUNCTIONS
99 throw std::logic_error(
"The dune-localfunctions module is required in oder to use"
100 " finite element gradients");
102 const auto& stencil = elemCtx.stencil(timeIdx);
104 const LocalFiniteElement& localFE = feCache_.get(elemCtx.element().type());
105 localFiniteElement_ = &localFE;
108 for (
unsigned faceIdx = 0; faceIdx < stencil.numInteriorFaces(); ++faceIdx) {
109 const auto& localFacePos = stencil.interiorFace(faceIdx).localPos();
114 localFE.localBasis().evaluateFunction(localFacePos, p1Value_[faceIdx]);
116 if (prepareGradients) {
118 std::vector<ShapeJacobian> localGradient;
119 localFE.localBasis().evaluateJacobian(localFacePos, localGradient);
124 const auto& geom = elemCtx.element().geometry();
125 const auto& jacInvT =
126 geom.jacobianInverseTransposed(localFacePos);
128 size_t numVertices = elemCtx.numDof(timeIdx);
129 for (
unsigned vertIdx = 0; vertIdx < numVertices; vertIdx++) {
130 jacInvT.mv(localGradient[vertIdx][0],
131 p1Gradient_[faceIdx][vertIdx]);
138 ParentType::template prepare<prepareValues, prepareGradients>(elemCtx, timeIdx);
152 template <
class QuantityCallback>
154 [[maybe_unused]]
unsigned fapIdx,
155 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
156 ->
typename std::remove_reference<typename QuantityCallback::ResultType>::type
158 if (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
159#if !HAVE_DUNE_LOCALFUNCTIONS
161 throw std::logic_error(
"The dune-localfunctions module is required in oder to use"
162 " finite element gradients");
164 using QuantityConstType =
typename std::remove_reference<typename QuantityCallback::ResultType>::type;
165 using QuantityType =
typename std::remove_const<QuantityConstType>::type;
166 using Toolbox = MathToolbox<QuantityType>;
170 QuantityType value(0.0);
171 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
172 if (std::is_same<QuantityType, Scalar>::value ||
173 elemCtx.focusDofIndex() == vertIdx)
174 value += quantityCallback(vertIdx)*p1Value_[fapIdx][vertIdx];
176 value += Toolbox::value(quantityCallback(vertIdx))*p1Value_[fapIdx][vertIdx];
197 template <
class QuantityCallback>
199 [[maybe_unused]]
unsigned fapIdx,
200 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
201 ->
typename std::remove_reference<typename QuantityCallback::ResultType>::type
203 if (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
204#if !HAVE_DUNE_LOCALFUNCTIONS
206 throw std::logic_error(
"The dune-localfunctions module is required in oder to use"
207 " finite element gradients");
209 using QuantityConstType =
typename std::remove_reference<typename QuantityCallback::ResultType>::type;
210 using QuantityType =
typename std::remove_const<QuantityConstType>::type;
212 using RawFieldType =
decltype(std::declval<QuantityType>()[0]);
213 using FieldType =
typename std::remove_const<typename std::remove_reference<RawFieldType>::type>::type;
215 using Toolbox = MathToolbox<FieldType>;
219 QuantityType value(0.0);
220 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
221 if (std::is_same<QuantityType, Scalar>::value ||
222 elemCtx.focusDofIndex() == vertIdx)
224 const auto& tmp = quantityCallback(vertIdx);
225 for (
unsigned k = 0; k < tmp.size(); ++k)
226 value[k] += tmp[k]*p1Value_[fapIdx][vertIdx];
229 const auto& tmp = quantityCallback(vertIdx);
230 for (
unsigned k = 0; k < tmp.size(); ++k)
231 value[k] += Toolbox::value(tmp[k])*p1Value_[fapIdx][vertIdx];
253 template <
class QuantityCallback,
class EvalDimVector>
255 [[maybe_unused]]
const ElementContext& elemCtx,
256 [[maybe_unused]]
unsigned fapIdx,
257 [[maybe_unused]]
const QuantityCallback& quantityCallback)
const
259 if (getPropValue<TypeTag, Properties::UseP1FiniteElementGradients>()) {
260#if !HAVE_DUNE_LOCALFUNCTIONS
262 throw std::logic_error(
"The dune-localfunctions module is required in oder to use"
263 " finite element gradients");
265 using QuantityConstType =
typename std::remove_reference<typename QuantityCallback::ResultType>::type;
266 using QuantityType =
typename std::remove_const<QuantityConstType>::type;
271 for (
unsigned vertIdx = 0; vertIdx < elemCtx.numDof(0); ++vertIdx) {
272 if (std::is_same<QuantityType, Scalar>::value ||
273 elemCtx.focusDofIndex() == vertIdx)
275 const auto& dofVal = quantityCallback(vertIdx);
276 const auto& tmp = p1Gradient_[fapIdx][vertIdx];
277 for (
int dimIdx = 0; dimIdx < dim; ++ dimIdx)
278 quantityGrad[dimIdx] += dofVal*tmp[dimIdx];
281 const auto& dofVal = quantityCallback(vertIdx);
282 const auto& tmp = p1Gradient_[fapIdx][vertIdx];
283 for (
int dimIdx = 0; dimIdx < dim; ++ dimIdx)
284 quantityGrad[dimIdx] += scalarValue(dofVal)*tmp[dimIdx];
307 template <
class QuantityCallback>
310 const QuantityCallback& quantityCallback)
328 template <
class QuantityCallback,
class EvalDimVector>
330 const ElementContext& elemCtx,
332 const QuantityCallback& quantityCallback)
const
335#if HAVE_DUNE_LOCALFUNCTIONS
336 static LocalFiniteElementCache& localFiniteElementCache()
341#if HAVE_DUNE_LOCALFUNCTIONS
342 static LocalFiniteElementCache feCache_;
344 const LocalFiniteElement* localFiniteElement_;
345 std::vector<Dune::FieldVector<Scalar, 1>> p1Value_[maxFap];
346 DimVector p1Gradient_[maxFap][maxDof];
350#if HAVE_DUNE_LOCALFUNCTIONS
351template<
class TypeTag>
352typename P1FeGradientCalculator<TypeTag>::LocalFiniteElementCache
353P1FeGradientCalculator<TypeTag>::feCache_;
This class calculates gradients of arbitrary quantities at flux integration points using the two-poin...
Definition: fvbasegradientcalculator.hh:47
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:284
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:201
auto calculateScalarValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const -> typename std::remove_reference< decltype(quantityCallback.operator()(0))>::type
Calculates the value of an arbitrary scalar quantity at any interior flux approximation point.
Definition: fvbasegradientcalculator.hh:95
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:263
auto calculateVectorValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const -> typename std::remove_reference< decltype(quantityCallback.operator()(0))>::type
Calculates the value of an arbitrary vectorial quantity at any interior flux approximation point.
Definition: fvbasegradientcalculator.hh:141
This class calculates gradients of arbitrary quantities at flux integration points using first order ...
Definition: p1fegradientcalculator.hh:60
auto calculateScalarValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const -> typename std::remove_reference< typename QuantityCallback::ResultType >::type
Calculates the value of an arbitrary quantity at any interior flux approximation point.
Definition: p1fegradientcalculator.hh:153
auto calculateVectorValue(const ElementContext &elemCtx, unsigned fapIdx, const QuantityCallback &quantityCallback) const -> typename std::remove_reference< typename QuantityCallback::ResultType >::type
Calculates the value of an arbitrary quantity at any interior flux approximation point.
Definition: p1fegradientcalculator.hh:198
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:329
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:308
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:93
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:254
Definition: blackoilboundaryratevector.hh:37
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:235
Declares the basic properties used by the common infrastructure of the vertex-centered finite volume ...