28#ifndef EWOMS_FV_BASE_GRADIENT_CALCULATOR_HH
29#define EWOMS_FV_BASE_GRADIENT_CALCULATOR_HH
31#include <dune/common/fvector.hh>
41template<
class TypeTag>
42class EcfvDiscretization;
50template<
class TypeTag>
59 enum { dim = GridView::dimension };
60 enum { dimWorld = GridView::dimensionworld };
64 enum { maxFap = 2 << dim };
66 using DimVector = Dune::FieldVector<Scalar, dimWorld>;
67 using EvalDimVector = Dune::FieldVector<Evaluation, dimWorld>;
84 template <
bool prepareValues = true,
bool prepareGradients = true>
85 void prepare(
const ElementContext&,
unsigned)
99 template <
class QuantityCallback>
102 const QuantityCallback& quantityCallback)
const
103 -> std::remove_reference_t<
decltype(quantityCallback.operator()(0))>
105 using RawReturnType =
decltype(quantityCallback.operator()(0));
106 using ReturnType = std::remove_const_t<std::remove_reference_t<RawReturnType>>;
108 Scalar interiorDistance;
109 Scalar exteriorDistance;
110 computeDistances_(interiorDistance, exteriorDistance, elemCtx, fapIdx);
112 const auto& face = elemCtx.stencil(0).interiorFace(fapIdx);
113 const auto i = face.interiorIndex();
114 const auto j = face.exteriorIndex();
115 const auto focusDofIdx = elemCtx.focusDofIndex();
119 if (i == focusDofIdx) {
120 value = quantityCallback(i) * interiorDistance;
122 value = getValue(quantityCallback(i)) * interiorDistance;
125 if (j == focusDofIdx) {
126 value += quantityCallback(j) * exteriorDistance;
129 value += getValue(quantityCallback(j)) * exteriorDistance;
132 value /= interiorDistance + exteriorDistance;
148 template <
class QuantityCallback>
151 const QuantityCallback& quantityCallback)
const
152 -> std::remove_reference_t<
decltype(quantityCallback.operator()(0))>
154 using RawReturnType =
decltype(quantityCallback.operator()(0));
155 using ReturnType = std::remove_const_t<std::remove_reference_t<RawReturnType>>;
157 Scalar interiorDistance;
158 Scalar exteriorDistance;
159 computeDistances_(interiorDistance, exteriorDistance, elemCtx, fapIdx);
161 const auto& face = elemCtx.stencil(0).interiorFace(fapIdx);
162 const auto i = face.interiorIndex();
163 const auto j = face.exteriorIndex();
164 const auto focusDofIdx = elemCtx.focusDofIndex();
168 if (i == focusDofIdx) {
169 value = quantityCallback(i);
170 for (
int k = 0; k < value.size(); ++k) {
171 value[k] *= interiorDistance;
175 const auto& dofVal = getValue(quantityCallback(i));
176 for (
int k = 0; k < dofVal.size(); ++k) {
177 value[k] = getValue(dofVal[k]) * interiorDistance;
181 if (j == focusDofIdx) {
182 const auto& dofVal = quantityCallback(j);
183 for (
int k = 0; k < dofVal.size(); ++k) {
184 value[k] += dofVal[k] * exteriorDistance;
188 const auto& dofVal = quantityCallback(j);
189 for (
int k = 0; k < dofVal.size(); ++k) {
190 value[k] += getValue(dofVal[k]) * exteriorDistance;
194 const Scalar totDistance = interiorDistance + exteriorDistance;
195 for (
int k = 0; k < value.size(); ++k) {
196 value[k] /= totDistance;
213 template <
class QuantityCallback>
215 const ElementContext& elemCtx,
217 const QuantityCallback& quantityCallback)
const
219 const auto& stencil = elemCtx.stencil(0);
220 const auto& face = stencil.interiorFace(fapIdx);
222 const auto i = face.interiorIndex();
223 const auto j = face.exteriorIndex();
224 const auto focusIdx = elemCtx.focusDofIndex();
226 const auto& interiorPos = stencil.subControlVolume(i).globalPos();
227 const auto& exteriorPos = stencil.subControlVolume(j).globalPos();
231 deltay = getValue(quantityCallback(j)) - quantityCallback(i);
233 else if (j == focusIdx) {
234 deltay = quantityCallback(j) - getValue(quantityCallback(i));
237 deltay = getValue(quantityCallback(j)) - getValue(quantityCallback(i));
240 Scalar distSquared = 0.0;
241 for (
unsigned dimIdx = 0; dimIdx < dimWorld; ++dimIdx) {
242 const Scalar tmp = exteriorPos[dimIdx] - interiorPos[dimIdx];
243 distSquared += tmp * tmp;
250 for (
unsigned dimIdx = 0; dimIdx < dimWorld; ++dimIdx) {
251 const Scalar tmp = exteriorPos[dimIdx] - interiorPos[dimIdx];
252 quantityGrad[dimIdx] = deltay *( tmp / distSquared);
270 template <
class QuantityCallback>
273 const QuantityCallback& quantityCallback)
274 ->
decltype(quantityCallback.boundaryValue())
275 {
return quantityCallback.boundaryValue(); }
291 template <
class QuantityCallback>
293 const ElementContext& elemCtx,
295 const QuantityCallback& quantityCallback)
const
297 const auto& stencil = elemCtx.stencil(0);
298 const auto& face = stencil.boundaryFace(faceIdx);
301 if (face.interiorIndex() == elemCtx.focusDofIndex()) {
302 deltay = quantityCallback.boundaryValue() - quantityCallback(face.interiorIndex());
305 deltay = getValue(quantityCallback.boundaryValue()) -
306 getValue(quantityCallback(face.interiorIndex()));
309 const auto& boundaryFacePos = face.integrationPos();
310 const auto& interiorPos = stencil.subControlVolume(face.interiorIndex()).center();
312 Scalar distSquared = 0;
313 for (
unsigned dimIdx = 0; dimIdx < dimWorld; ++dimIdx) {
314 const Scalar tmp = boundaryFacePos[dimIdx] - interiorPos[dimIdx];
315 distSquared += tmp * tmp;
323 for (
unsigned dimIdx = 0; dimIdx < dimWorld; ++dimIdx) {
324 const Scalar tmp = boundaryFacePos[dimIdx] - interiorPos[dimIdx];
325 quantityGrad[dimIdx] = deltay * (tmp / distSquared);
330 void computeDistances_(Scalar& interiorDistance,
331 Scalar& exteriorDistance,
332 const ElementContext& elemCtx,
333 unsigned fapIdx)
const
335 const auto& stencil = elemCtx.stencil(0);
336 const auto& face = stencil.interiorFace(fapIdx);
340 const auto& normal = face.normal();
341 const auto i = face.interiorIndex();
342 const auto j = face.exteriorIndex();
343 const auto& interiorPos = stencil.subControlVolume(i).globalPos();
344 const auto& exteriorPos = stencil.subControlVolume(j).globalPos();
345 const auto& integrationPos = face.integrationPos();
347 interiorDistance = 0.0;
348 exteriorDistance = 0.0;
349 for (
unsigned dimIdx = 0; dimIdx < dimWorld; ++dimIdx) {
350 interiorDistance += (interiorPos[dimIdx] - integrationPos[dimIdx]) * normal[dimIdx];
351 exteriorDistance += (exteriorPos[dimIdx] - integrationPos[dimIdx]) * normal[dimIdx];
354 interiorDistance = std::sqrt(std::abs(interiorDistance));
355 exteriorDistance = std::sqrt(std::abs(exteriorDistance));
Defines a type tags and some fundamental properties all models.
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
void prepare(const ElementContext &, unsigned)
Precomputes the common values to calculate gradients and values of quantities at every interior flux ...
Definition: fvbasegradientcalculator.hh:85
static void registerParameters()
Register all run-time parameters for the gradient calculator of the base class of the discretization.
Definition: fvbasegradientcalculator.hh:74
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
Declare the properties used by the infrastructure code of the finite volume discretizations.
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