fvbaseelementcontext.hh
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  Copyright (C) 2008-2013 by Andreas Lauser
5 
6  This file is part of the Open Porous Media project (OPM).
7 
8  OPM is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 2 of the License, or
11  (at your option) any later version.
12 
13  OPM is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with OPM. If not, see <http://www.gnu.org/licenses/>.
20 */
26 #ifndef EWOMS_FV_BASE_ELEMENT_CONTEXT_HH
27 #define EWOMS_FV_BASE_ELEMENT_CONTEXT_HH
28 
29 #include "fvbaseproperties.hh"
30 
31 #include <dune/common/fvector.hh>
32 
33 #include <vector>
34 
35 namespace Ewoms {
36 
43 template<class TypeTag>
45 {
46  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
47  typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
48  typedef typename GET_PROP_TYPE(TypeTag, IntensiveQuantities) IntensiveQuantities;
49  typedef typename GET_PROP_TYPE(TypeTag, ExtensiveQuantities) ExtensiveQuantities;
50 
51  // the history size of the time discretization in number of steps
52  enum { timeDiscHistorySize = GET_PROP_VALUE(TypeTag, TimeDiscHistorySize) };
53 
54  struct DofStore_ {
55  IntensiveQuantities intensiveQuantities[timeDiscHistorySize];
56  PrimaryVariables priVars[timeDiscHistorySize];
57  const IntensiveQuantities *thermodynamicHint[timeDiscHistorySize];
58  };
59  typedef std::vector<DofStore_> DofVarsVector;
60  typedef std::vector<ExtensiveQuantities> ExtensiveQuantitiesVector;
61 
62  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
63  typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
64  typedef typename GET_PROP_TYPE(TypeTag, Model) Model;
65  typedef typename GET_PROP_TYPE(TypeTag, Stencil) Stencil;
66  typedef typename GET_PROP_TYPE(TypeTag, GradientCalculator) GradientCalculator;
67  typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
68 
69  typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
70  typedef typename GridView::template Codim<0>::Entity Element;
71 
72  static const int dim = GridView::dimension;
73  static const int numEq = GET_PROP_VALUE(TypeTag, NumEq);
74  static const int requireScvCenterGradients =
75  GET_PROP_VALUE(TypeTag, RequireScvCenterGradients);
76 
77  typedef typename GridView::ctype CoordScalar;
78  typedef Dune::FieldVector<CoordScalar, dim> GlobalPosition;
79 
80  // we don't allow copies of element contexts!
82  {}
83 
84 public:
88  explicit FvBaseElementContext(const Simulator &simulator)
89  : gridView_(simulator.gridView())
91  {
92  // remember the simulator object
94  }
95 
103  void updateAll(const Element &elem)
104  {
105  updateStencil(elem);
108  }
109 
116  void updateStencil(const Element &elem)
117  {
118  // remember the current element
119  elemPtr_ = &elem;
120 
121  // update the stencil. the center gradients are kind of expensive to calculate
122  // and most models don't need them, so that we only do this if the model needs
123  // them
124  stencil_.update(elem);
125  if (requireScvCenterGradients)
126  stencil_.updateCenterGradients();
127 
128  // resize the arrays containing the flux and the volume variables
129  dofVars_.resize(stencil_.numDof());
130  extensiveQuantities_.resize(stencil_.numInteriorFaces());
131  }
132 
139  void updateStencilTopology(const Element &elem)
140  {
141  // remember the current element
142  elemPtr_ = &elem;
143 
144  // update the finite element geometry
145  stencil_.updateTopology(elem);
146  }
147 
153  {
154  for (int timeIdx = 0; timeIdx < timeDiscHistorySize; ++ timeIdx)
155  updateIntensiveQuantities(timeIdx);
156  }
157 
164  void updateIntensiveQuantities(int timeIdx)
165  { updateIntensiveQuantities_(timeIdx, numDof(/*timeIdx=*/0)); }
166 
174  { updateIntensiveQuantities_(timeIdx, numPrimaryDof(/*timeIdx=*/0)); }
175 
186  void updateIntensiveQuantities(const PrimaryVariables &priVars, int dofIdx, int timeIdx)
187  {
188  updateSingleIntQuants_(priVars, dofIdx, timeIdx);
189 
190  // update gradients inside a sub control volume
191  int nDof = numDof(/*timeIdx=*/0);
192  for (int gradDofIdx = 0; gradDofIdx < nDof; gradDofIdx++) {
193  dofVars_[gradDofIdx].intensiveQuantities[timeIdx].updateScvGradients(/*context=*/*this,
194  gradDofIdx,
195  timeIdx);
196  }
197  }
198 
204  {
205  updateExtensiveQuantities(/*timeIdx=*/0);
206  }
207 
215  void updateExtensiveQuantities(int timeIdx)
216  {
217  gradientCalculator_.prepare(/*context=*/*this, timeIdx);
218 
219  for (int fluxIdx = 0; fluxIdx < numInteriorFaces(timeIdx); fluxIdx++) {
220  extensiveQuantities_[fluxIdx].update(/*context=*/ *this,
221  /*localIndex=*/fluxIdx,
222  timeIdx);
223  }
224  }
225 
229  const Simulator &simulator() const
230  { return *simulatorPtr_; }
231 
235  const Problem &problem() const
236  { return simulatorPtr_->problem(); }
237 
241  const Model &model() const
242  { return simulatorPtr_->model(); }
243 
247  const GridView &gridView() const
248  { return gridView_; }
249 
253  const Element &element() const
254  { return *elemPtr_; }
255 
259  int numDof(int timeIdx) const
260  { return stencil(timeIdx).numDof(); }
261 
265  int numPrimaryDof(int timeIdx) const
266  { return stencil(timeIdx).numPrimaryDof(); }
267 
272  int numInteriorFaces(int timeIdx) const
273  { return stencil(timeIdx).numInteriorFaces(); }
274 
279  int numBoundaryFaces(int timeIdx) const
280  { return stencil(timeIdx).numBoundaryFaces(); }
281 
288  const Stencil &stencil(int timeIdx) const
289  { return stencil_; }
290 
299  const GlobalPosition &pos(int dofIdx, int timeIdx) const
300  { return stencil_.subControlVolume(dofIdx).globalPos(); }
301 
310  int globalSpaceIndex(int dofIdx, int timeIdx) const
311  { return stencil(timeIdx).globalSpaceIndex(dofIdx); }
312 
313 
323  Scalar dofVolume(int dofIdx, int timeIdx) const
324  { return stencil(timeIdx).subControlVolume(dofIdx).volume(); }
325 
336  Scalar dofTotalVolume(int dofIdx, int timeIdx) const
337  { return model().dofTotalVolume(globalSpaceIndex(dofIdx, timeIdx)); }
338 
343  bool onBoundary() const
344  { return element().hasBoundaryIntersections(); }
345 
356  const IntensiveQuantities &intensiveQuantities(int dofIdx, int timeIdx) const
357  {
358  assert(0 <= dofIdx && dofIdx < numDof(timeIdx));
359  return dofVars_[dofIdx].intensiveQuantities[timeIdx];
360  }
361 
370  const IntensiveQuantities *thermodynamicHint(int dofIdx, int timeIdx) const
371  {
372  assert(0 <= dofIdx && dofIdx < numDof(timeIdx));
373  return dofVars_[dofIdx].thermodynamicHint[timeIdx];
374  }
378  IntensiveQuantities &intensiveQuantities(int dofIdx, int timeIdx)
379  {
380  assert(0 <= dofIdx && dofIdx < numDof(timeIdx));
381  return dofVars_[dofIdx].intensiveQuantities[timeIdx];
382  }
383 
392  PrimaryVariables &primaryVars(int dofIdx, int timeIdx)
393  {
394  assert(0 <= dofIdx && dofIdx < numDof(timeIdx));
395  return dofVars_[dofIdx].priVars[timeIdx];
396  }
400  const PrimaryVariables &primaryVars(int dofIdx, int timeIdx) const
401  {
402  assert(0 <= dofIdx && dofIdx < numDof(timeIdx));
403  return dofVars_[dofIdx].priVars[timeIdx];
404  }
405 
411  void saveIntensiveQuantities(int dofIdx)
412  {
413  assert(0 <= dofIdx && dofIdx < numDof(/*timeIdx=*/0));
414 
415  intensiveQuantitiesSaved_ = dofVars_[dofIdx].intensiveQuantities[/*timeIdx=*/0];
416  priVarsSaved_ = dofVars_[dofIdx].priVars[/*timeIdx=*/0];
417  }
418 
424  void restoreIntensiveQuantities(int dofIdx)
425  {
426  dofVars_[dofIdx].priVars[/*timeIdx=*/0] = priVarsSaved_;
427  dofVars_[dofIdx].intensiveQuantities[/*timeIdx=*/0] = intensiveQuantitiesSaved_;
428  }
429 
434  const GradientCalculator& gradientCalculator() const
435  { return gradientCalculator_; }
436 
445  const ExtensiveQuantities &extensiveQuantities(int fluxIdx, int timeIdx) const
446  { return extensiveQuantities_[fluxIdx]; }
447 
448 protected:
454  void updateIntensiveQuantities_(int timeIdx, int numDof)
455  {
456  // update the intensive quantities for the whole history
457  const SolutionVector &globalSol = model().solution(timeIdx);
458 
459  // update the non-gradient quantities
460  for (int dofIdx = 0; dofIdx < numDof; dofIdx++) {
461  int globalIdx = globalSpaceIndex(dofIdx, timeIdx);
462  const PrimaryVariables& dofSol = globalSol[globalIdx];
463 
464  dofVars_[dofIdx].thermodynamicHint[timeIdx] =
465  model().thermodynamicHint(globalIdx, timeIdx);
466 
467  const auto *cachedIntQuants = model().cachedIntensiveQuantities(globalIdx, timeIdx);
468  if (cachedIntQuants) {
469  dofVars_[dofIdx].priVars[timeIdx] = dofSol;
470  dofVars_[dofIdx].intensiveQuantities[timeIdx] = *cachedIntQuants;
471  }
472  else {
473  updateSingleIntQuants_(dofSol, dofIdx, timeIdx);
474  model().updateCachedIntensiveQuantities(dofVars_[dofIdx].intensiveQuantities[timeIdx],
475  globalIdx,
476  timeIdx);
477  }
478  }
479 
480  // update gradients
481  for (int dofIdx = 0; dofIdx < numDof; dofIdx++) {
482  dofVars_[dofIdx].intensiveQuantities[timeIdx].updateScvGradients(/*context=*/*this,
483  dofIdx,
484  timeIdx);
485  }
486  }
487 
488  void updateSingleIntQuants_(const PrimaryVariables &priVars, int dofIdx, int timeIdx)
489  {
490  dofVars_[dofIdx].priVars[timeIdx] = priVars;
491  dofVars_[dofIdx].intensiveQuantities[timeIdx].update(/*context=*/*this, dofIdx, timeIdx);
492  }
493 
494  DofVarsVector dofVars_;
495 
496  IntensiveQuantities intensiveQuantitiesSaved_;
497  PrimaryVariables priVarsSaved_;
498 
499  GradientCalculator gradientCalculator_;
500 
501  ExtensiveQuantitiesVector extensiveQuantities_;
502 
503  const Simulator *simulatorPtr_;
504  const Element *elemPtr_;
505  const GridView gridView_;
506  Stencil stencil_;
507 };
508 
509 } // namespace Ewoms
510 
511 #endif
void updateAll(const Element &elem)
Construct all volume and extensive quantities of an element from scratch.
Definition: fvbaseelementcontext.hh:103
void updateIntensiveQuantities_(int timeIdx, int numDof)
Update the first 'n' intensive quantities objects from the primary variables.
Definition: fvbaseelementcontext.hh:454
const GlobalPosition & pos(int dofIdx, int timeIdx) const
Return the position of a local entities in global coordinates.
Definition: fvbaseelementcontext.hh:299
void updateExtensiveQuantities(int timeIdx)
Compute the extensive quantities of all sub-control volume faces of the current element for a single ...
Definition: fvbaseelementcontext.hh:215
DofVarsVector dofVars_
Definition: fvbaseelementcontext.hh:494
This class stores an array of IntensiveQuantities objects, one intensive quantities object for each o...
Definition: fvbaseelementcontext.hh:44
const Model & model() const
Return a reference to the model.
Definition: fvbaseelementcontext.hh:241
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:189
const Stencil & stencil(int timeIdx) const
Return the current finite element geometry.
Definition: fvbaseelementcontext.hh:288
Declare the properties used by the infrastructure code of the finite volume discretizations.
const IntensiveQuantities & intensiveQuantities(int dofIdx, int timeIdx) const
Return a reference to the intensive quantities of a sub-control volume at a given time...
Definition: fvbaseelementcontext.hh:356
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
const Simulator * simulatorPtr_
Definition: fvbaseelementcontext.hh:503
const Element * elemPtr_
Definition: fvbaseelementcontext.hh:504
const Problem & problem() const
Return a reference to the problem.
Definition: fvbaseelementcontext.hh:235
void updateIntensiveQuantities(int timeIdx)
Compute the intensive quantities of all sub-control volumes of the current element for a single time ...
Definition: fvbaseelementcontext.hh:164
const Element & element() const
Return the current element.
Definition: fvbaseelementcontext.hh:253
GradientCalculator gradientCalculator_
Definition: fvbaseelementcontext.hh:499
int globalSpaceIndex(int dofIdx, int timeIdx) const
Return the global spatial index for a sub-control volume.
Definition: fvbaseelementcontext.hh:310
IntensiveQuantities intensiveQuantitiesSaved_
Definition: fvbaseelementcontext.hh:496
ExtensiveQuantitiesVector extensiveQuantities_
Definition: fvbaseelementcontext.hh:501
PrimaryVariables & primaryVars(int dofIdx, int timeIdx)
Return the primary variables for a given local index.
Definition: fvbaseelementcontext.hh:392
void updateStencilTopology(const Element &elem)
Update the topological part of the stencil, but nothing else.
Definition: fvbaseelementcontext.hh:139
void updateAllExtensiveQuantities()
Compute the extensive quantities of all sub-control volume faces of the current element for all time ...
Definition: fvbaseelementcontext.hh:203
Scalar dofVolume(int dofIdx, int timeIdx) const
Return the element-local volume associated with a degree of freedom.
Definition: fvbaseelementcontext.hh:323
const Simulator & simulator() const
Return a reference to the simulator.
Definition: fvbaseelementcontext.hh:229
int numDof(int timeIdx) const
Return the number of sub-control volumes of the current element.
Definition: fvbaseelementcontext.hh:259
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:73
Stencil stencil_
Definition: fvbaseelementcontext.hh:506
const GridView gridView_
Definition: fvbaseelementcontext.hh:505
Definition: baseauxiliarymodule.hh:35
PrimaryVariables priVarsSaved_
Definition: fvbaseelementcontext.hh:497
int numBoundaryFaces(int timeIdx) const
Return the number of boundary faces which need to be considered for the flux apporixmation.
Definition: fvbaseelementcontext.hh:279
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:176
void updateSingleIntQuants_(const PrimaryVariables &priVars, int dofIdx, int timeIdx)
Definition: fvbaseelementcontext.hh:488
void updateIntensiveQuantities(const PrimaryVariables &priVars, int dofIdx, int timeIdx)
Compute the intensive quantities of a single sub-control volume of the current element for a single t...
Definition: fvbaseelementcontext.hh:186
const ExtensiveQuantities & extensiveQuantities(int fluxIdx, int timeIdx) const
Return a reference to the extensive quantities of a sub-control volume face.
Definition: fvbaseelementcontext.hh:445
void restoreIntensiveQuantities(int dofIdx)
Restores the intensive quantities for a degree of freedom from internal memory.
Definition: fvbaseelementcontext.hh:424
int numInteriorFaces(int timeIdx) const
Return the number of non-boundary faces which need to be considered for the flux apporixmation.
Definition: fvbaseelementcontext.hh:272
void updateAllIntensiveQuantities()
Compute the intensive quantities of all sub-control volumes of the current element for all time indic...
Definition: fvbaseelementcontext.hh:152
bool onBoundary() const
Returns whether the current element is on the domain's boundary.
Definition: fvbaseelementcontext.hh:343
const GridView & gridView() const
Return a reference to the grid view.
Definition: fvbaseelementcontext.hh:247
void updatePrimaryIntensiveQuantities(int timeIdx)
Compute the intensive quantities of all sub-control volumes of the current element for a single time ...
Definition: fvbaseelementcontext.hh:173
IntensiveQuantities & intensiveQuantities(int dofIdx, int timeIdx)
Return a reference to the intensive quantities of a sub-control volume at a given time...
Definition: fvbaseelementcontext.hh:378
FvBaseElementContext(const Simulator &simulator)
The constructor.
Definition: fvbaseelementcontext.hh:88
const IntensiveQuantities * thermodynamicHint(int dofIdx, int timeIdx) const
Return the thermodynamic hint for a given local index.
Definition: fvbaseelementcontext.hh:370
Scalar dofTotalVolume(int dofIdx, int timeIdx) const
Return the total volume associated with a degree of freedom.
Definition: fvbaseelementcontext.hh:336
void saveIntensiveQuantities(int dofIdx)
Stash the intensive quantities for a degree of freedom on internal memory.
Definition: fvbaseelementcontext.hh:411
int numPrimaryDof(int timeIdx) const
Return the number of primary degrees of freedom of the current element.
Definition: fvbaseelementcontext.hh:265
const GradientCalculator & gradientCalculator() const
Return a reference to the gradient calculation class of the chosen spatial discretization.
Definition: fvbaseelementcontext.hh:434
void updateStencil(const Element &elem)
Compute the finite volume geometry for an element.
Definition: fvbaseelementcontext.hh:116
const PrimaryVariables & primaryVars(int dofIdx, int timeIdx) const
Return the primary variables for a given local index.
Definition: fvbaseelementcontext.hh:400