28 #ifndef EWOMS_FV_BASE_ELEMENT_CONTEXT_HH 29 #define EWOMS_FV_BASE_ELEMENT_CONTEXT_HH 31 #include <dune/common/fvector.hh> 53 template<
class TypeTag>
64 enum { timeDiscHistorySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>() };
68 std::array<const PrimaryVariables*, timeDiscHistorySize> priVars;
71 using ExtensiveQuantitiesVector = std::vector<ExtensiveQuantities>;
81 using Element =
typename GridView::template Codim<0>::Entity;
83 static const unsigned dimWorld = GridView::dimensionworld;
85 using CoordScalar =
typename GridView::ctype;
86 using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
101 enableStorageCache_ = Parameters::Get<Parameters::EnableStorageCache>();
104 static void *
operator new(std::size_t size)
107 static void operator delete(
void *ptr)
108 { aligned_free(ptr); }
119 asImp_().updateStencil(elem);
120 asImp_().updateAllIntensiveQuantities();
121 asImp_().updateAllExtensiveQuantities();
138 stencil_.update(elem);
141 dofVars_.resize(stencil_.numDof());
142 extensiveQuantities_.resize(stencil_.numInteriorFaces());
157 stencil_.updatePrimaryTopology(elem);
159 dofVars_.resize(stencil_.numPrimaryDof());
174 stencil_.updateTopology(elem);
183 if (!enableStorageCache_) {
186 for (
unsigned timeIdx = 0; timeIdx < timeDiscHistorySize; ++timeIdx) {
187 asImp_().updateIntensiveQuantities(timeIdx);
194 asImp_().updateIntensiveQuantities(0);
227 { asImp_().updateSingleIntQuants_(priVars, dofIdx, timeIdx); }
234 { asImp_().updateExtensiveQuantities(0); }
245 gradientCalculator_.prepare(asImp_(), timeIdx);
247 for (
unsigned fluxIdx = 0; fluxIdx <
numInteriorFaces(timeIdx); ++fluxIdx) {
248 extensiveQuantities_[fluxIdx].update(asImp_(),
262 { focusDofIdx_ = dofIdx; }
270 {
return focusDofIdx_; }
278 {
return this->
model().linearizer().getLinearizationType(); }
284 {
return *simulatorPtr_; }
290 {
return simulatorPtr_->problem(); }
296 {
return simulatorPtr_->model(); }
302 {
return gridView_; }
308 {
return *elemPtr_; }
313 std::size_t
numDof(
unsigned timeIdx)
const 314 {
return stencil(timeIdx).numDof(); }
320 {
return stencil(timeIdx).numPrimaryDof(); }
327 {
return stencil(timeIdx).numInteriorFaces(); }
334 {
return stencil(timeIdx).numBoundaryFaces(); }
353 decltype(
auto)
pos(
unsigned dofIdx,
unsigned)
const 354 {
return stencil_.subControlVolume(dofIdx).globalPos(); }
365 {
return stencil(timeIdx).globalSpaceIndex(dofIdx); }
376 Scalar
dofVolume(
unsigned dofIdx,
unsigned timeIdx)
const 377 {
return stencil(timeIdx).subControlVolume(dofIdx).volume(); }
397 {
return element().hasBoundaryIntersections(); }
412 assert(dofIdx <
numDof(timeIdx));
414 if (enableStorageCache_ && timeIdx != 0 &&
problem().recycleFirstIterationStorage()) {
415 throw std::logic_error(
"If caching of the storage term is enabled, only the intensive quantities " 416 "for the most-recent substep (i.e. time index 0) are available!");
420 return dofVars_[dofIdx].intensiveQuantities[timeIdx];
433 assert(dofIdx <
numDof(timeIdx));
434 return dofVars_[dofIdx].thermodynamicHint[timeIdx];
442 assert(dofIdx <
numDof(timeIdx));
443 return dofVars_[dofIdx].intensiveQuantities[timeIdx];
454 const PrimaryVariables&
primaryVars(
unsigned dofIdx,
unsigned timeIdx)
const 456 assert(dofIdx <
numDof(timeIdx));
457 return *dofVars_[dofIdx].priVars[timeIdx];
467 {
return stashedDofIdx_ != -1; }
476 {
return stashedDofIdx_; }
485 assert(dofIdx <
numDof(0));
487 intensiveQuantitiesStashed_ = dofVars_[dofIdx].intensiveQuantities[0];
488 priVarsStashed_ = *dofVars_[dofIdx].priVars[0];
489 stashedDofIdx_ =
static_cast<int>(dofIdx);
499 dofVars_[dofIdx].priVars[0] = &priVarsStashed_;
500 dofVars_[dofIdx].intensiveQuantities[0] = intensiveQuantitiesStashed_;
509 {
return gradientCalculator_; }
520 {
return extensiveQuantities_[fluxIdx]; }
529 {
return enableStorageCache_; }
535 { enableStorageCache_ = yesno; }
538 Implementation& asImp_()
539 {
return *
static_cast<Implementation*
>(
this); }
541 const Implementation& asImp_()
const 542 {
return *
static_cast<const Implementation*
>(
this); }
553 const SolutionVector& globalSol =
model().solution(timeIdx);
555 const unsigned intensiveHistorySize =
model().cachedIntensiveQuantityHistorySize();
558 for (
unsigned dofIdx = 0; dofIdx <
numDof; ++dofIdx) {
560 const PrimaryVariables& dofSol = globalSol[globalIdx];
561 dofVars_[dofIdx].priVars[timeIdx] = &dofSol;
563 if (timeIdx >= intensiveHistorySize) {
566 updateSingleIntQuants_(dofSol, dofIdx, timeIdx);
571 dofVars_[dofIdx].thermodynamicHint[timeIdx] =
model().thermodynamicHint(globalIdx, timeIdx);
572 const auto* cachedIntQuants =
model().cachedIntensiveQuantities(globalIdx, timeIdx);
573 if (cachedIntQuants) {
574 dofVars_[dofIdx].intensiveQuantities[timeIdx] = *cachedIntQuants;
577 updateSingleIntQuants_(dofSol, dofIdx, timeIdx);
586 void updateSingleIntQuants_(
const PrimaryVariables& priVars,
unsigned dofIdx,
unsigned timeIdx)
589 if (enableStorageCache_ && timeIdx != 0 &&
problem().recycleFirstIterationStorage()) {
590 throw std::logic_error(
"If caching of the storage term is enabled, only the intensive quantities " 591 "for the most-recent substep (i.e. time index 0) are available!");
595 dofVars_[dofIdx].priVars[timeIdx] = &priVars;
596 dofVars_[dofIdx].intensiveQuantities[timeIdx].update(asImp_(), dofIdx, timeIdx);
599 IntensiveQuantities intensiveQuantitiesStashed_;
600 PrimaryVariables priVarsStashed_;
602 GradientCalculator gradientCalculator_;
604 template<
class T>
using AlignedVector = std::vector<T, aligned_allocator<T, alignof(T)>>;
606 AlignedVector<DofStore_> dofVars_;
607 AlignedVector<ExtensiveQuantities> extensiveQuantities_;
609 const Simulator* simulatorPtr_{};
610 const Element* elemPtr_{};
611 const GridView gridView_;
614 int stashedDofIdx_{-1};
615 int focusDofIdx_{-1};
616 bool enableStorageCache_{
false};
void updateStencilTopology(const Element &elem)
Update the topological part of the stencil, but nothing else.
Definition: fvbaseelementcontext.hh:168
const GradientCalculator & gradientCalculator() const
Return a reference to the gradient calculation class of the chosen spatial discretization.
Definition: fvbaseelementcontext.hh:508
This is a stand-alone version of boost::alignment::aligned_allocator from Boost 1...
int stashedDofIdx() const
Return the (local) index of the DOF for which the primary variables were stashed. ...
Definition: fvbaseelementcontext.hh:475
const Simulator & simulator() const
Return a reference to the simulator.
Definition: fvbaseelementcontext.hh:283
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
const IntensiveQuantities * thermodynamicHint(unsigned dofIdx, unsigned timeIdx) const
Return the thermodynamic hint for a given local index.
Definition: fvbaseelementcontext.hh:431
void updateStencil(const Element &elem)
Compute the finite volume geometry for an element.
Definition: fvbaseelementcontext.hh:130
const Model & model() const
Return a reference to the model.
Definition: fvbaseelementcontext.hh:295
const GridView & gridView() const
Return a reference to the grid view.
Definition: fvbaseelementcontext.hh:301
void setFocusDofIndex(unsigned dofIdx)
Sets the degree of freedom on which the simulator is currently "focused" on.
Definition: fvbaseelementcontext.hh:261
const Stencil & stencil(unsigned) const
Return the current finite element geometry.
Definition: fvbaseelementcontext.hh:342
LinearizationType linearizationType() const
Returns the linearization type.
Definition: fvbaseelementcontext.hh:277
void setEnableStorageCache(bool yesno)
Specifies if the cache for the storage term ought to be used for this context.
Definition: fvbaseelementcontext.hh:534
bool haveStashedIntensiveQuantities() const
Returns true if no intensive quanties are stashed.
Definition: fvbaseelementcontext.hh:466
Scalar dofVolume(unsigned dofIdx, unsigned timeIdx) const
Return the element-local volume associated with a degree of freedom.
Definition: fvbaseelementcontext.hh:376
FvBaseElementContext(const Simulator &simulator)
The constructor.
Definition: fvbaseelementcontext.hh:95
void stashIntensiveQuantities(unsigned dofIdx)
Stash the intensive quantities for a degree of freedom on internal memory.
Definition: fvbaseelementcontext.hh:483
const IntensiveQuantities & intensiveQuantities(unsigned dofIdx, unsigned timeIdx) const
Return a reference to the intensive quantities of a sub-control volume at a given time...
Definition: fvbaseelementcontext.hh:409
const Problem & problem() const
Return a reference to the problem.
Definition: fvbaseelementcontext.hh:289
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
void updatePrimaryIntensiveQuantities(unsigned timeIdx)
Compute the intensive quantities of all sub-control volumes of the current element for a single time ...
Definition: fvbaseelementcontext.hh:213
This class stores an array of IntensiveQuantities objects, one intensive quantities object for each o...
Definition: fvbaseelementcontext.hh:54
const Element & element() const
Return the current element.
Definition: fvbaseelementcontext.hh:307
decltype(auto) pos(unsigned dofIdx, unsigned) const
Return the position of a local entities in global coordinates.
Definition: fvbaseelementcontext.hh:353
void updateIntensiveQuantities(const PrimaryVariables &priVars, unsigned dofIdx, unsigned timeIdx)
Compute the intensive quantities of a single sub-control volume of the current element for a single t...
Definition: fvbaseelementcontext.hh:226
Declare the properties used by the infrastructure code of the finite volume discretizations.
void updateAllIntensiveQuantities()
Compute the intensive quantities of all sub-control volumes of the current element for all time indic...
Definition: fvbaseelementcontext.hh:181
const PrimaryVariables & primaryVars(unsigned dofIdx, unsigned timeIdx) const
Return the primary variables for a given local index.
Definition: fvbaseelementcontext.hh:454
Definition: linearizationtype.hh:33
void updateIntensiveQuantities_(unsigned timeIdx, std::size_t numDof)
Update the first 'n' intensive quantities objects from the primary variables.
Definition: fvbaseelementcontext.hh:550
bool enableStorageCache() const
Returns true iff the cache for the storage term ought to be used for this context.
Definition: fvbaseelementcontext.hh:528
The common code for the linearizers of non-linear systems of equations.
Scalar dofTotalVolume(unsigned dofIdx, unsigned timeIdx) const
Return the total volume associated with a degree of freedom.
Definition: fvbaseelementcontext.hh:389
Declare the properties used by the infrastructure code of the finite volume discretizations.
void updatePrimaryStencil(const Element &elem)
Update the primary topological part of the stencil, but nothing else.
Definition: fvbaseelementcontext.hh:151
std::size_t numInteriorFaces(unsigned timeIdx) const
Return the number of non-boundary faces which need to be considered for the flux apporixmation.
Definition: fvbaseelementcontext.hh:326
void updateExtensiveQuantities(unsigned timeIdx)
Compute the extensive quantities of all sub-control volume faces of the current element for a single ...
Definition: fvbaseelementcontext.hh:243
void updateAll(const Element &elem)
Construct all volume and extensive quantities of an element from scratch.
Definition: fvbaseelementcontext.hh:117
void updateAllExtensiveQuantities()
Compute the extensive quantities of all sub-control volume faces of the current element for all time ...
Definition: fvbaseelementcontext.hh:233
void restoreIntensiveQuantities(unsigned dofIdx)
Restores the intensive quantities for a degree of freedom from internal memory.
Definition: fvbaseelementcontext.hh:497
IntensiveQuantities & intensiveQuantities(unsigned dofIdx, unsigned timeIdx)
Return a reference to the intensive quantities of a sub-control volume at a given time...
Definition: fvbaseelementcontext.hh:440
std::size_t numBoundaryFaces(unsigned timeIdx) const
Return the number of boundary faces which need to be considered for the flux apporixmation.
Definition: fvbaseelementcontext.hh:333
unsigned globalSpaceIndex(unsigned dofIdx, unsigned timeIdx) const
Return the global spatial index for a sub-control volume.
Definition: fvbaseelementcontext.hh:364
unsigned focusDofIndex() const
Returns the degree of freedom on which the simulator is currently "focused" on.
Definition: fvbaseelementcontext.hh:269
std::size_t numPrimaryDof(unsigned timeIdx) const
Return the number of primary degrees of freedom of the current element.
Definition: fvbaseelementcontext.hh:319
void updateIntensiveQuantities(unsigned timeIdx)
Compute the intensive quantities of all sub-control volumes of the current element for a single time ...
Definition: fvbaseelementcontext.hh:204
bool onBoundary() const
Returns whether the current element is on the domain's boundary.
Definition: fvbaseelementcontext.hh:396
const ExtensiveQuantities & extensiveQuantities(unsigned fluxIdx, unsigned) const
Return a reference to the extensive quantities of a sub-control volume face.
Definition: fvbaseelementcontext.hh:519
std::size_t numDof(unsigned timeIdx) const
Return the number of sub-control volumes of the current element.
Definition: fvbaseelementcontext.hh:313