ecfvstencil.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) 2009-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_ECFV_STENCIL_HH
27 #define EWOMS_ECFV_STENCIL_HH
28 
30 
31 #include <dune/grid/common/mcmgmapper.hh>
32 #include <dune/grid/common/intersectioniterator.hh>
33 #include <dune/geometry/type.hh>
34 #include <dune/common/fvector.hh>
35 #include <dune/common/version.hh>
36 
37 #include <vector>
38 
39 namespace Ewoms {
50 template <class Scalar, class GridView>
52 {
53  enum { dimWorld = GridView::dimensionworld };
54 
55  typedef typename GridView::ctype CoordScalar;
56  typedef typename GridView::Intersection Intersection;
57  typedef typename GridView::template Codim<0>::Entity Element;
58 #if ! DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
59  typedef typename GridView::template Codim<0>::EntityPointer ElementPointer;
60 #endif
61 
62  typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView,
63  Dune::MCMGElementLayout> ElementMapper;
64 
65  typedef Dune::FieldVector<CoordScalar, dimWorld> GlobalPosition;
66 
67  typedef Dune::FieldVector<Scalar, dimWorld> WorldVector;
68 
69 public:
70  typedef typename Element::Geometry LocalGeometry;
71 
81  {
82  public:
83 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
84  SubControlVolume(const Element &element)
85  : element_(element)
86 #else
87  SubControlVolume(const ElementPointer &elementPtr)
88  : elementPtr_(elementPtr)
89 #endif
90  { update(); }
91 
92 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
93  void update(const Element &element)
94  { element_ = element; }
95 #else
96  void update(const ElementPointer &elementPtr)
97  { elementPtr_ = elementPtr; }
98 #endif
99 
100  void update()
101  {
102 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
103  const auto &geometry = element_.geometry();
104 #else
105  const auto &geometry = elementPtr_->geometry();
106 #endif
107  centerPos_ = geometry.center();
108  volume_ = geometry.volume();
109  }
110 
114  const GlobalPosition &globalPos() const
115  { return centerPos_; }
116 
120  const GlobalPosition &center() const
121  { return centerPos_; }
122 
126  Scalar volume() const
127  { return volume_; }
128 
132 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
133  const LocalGeometry geometry() const
134  { return element_.geometry(); }
135 #else
136  const LocalGeometry geometry() const
137  { return elementPtr_->geometry(); }
138 #endif
139 
140  private:
141  GlobalPosition centerPos_;
142  Scalar volume_;
143 
144 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
145  Element element_;
146 #else
147  ElementPointer elementPtr_;
148 #endif
149  };
150 
155  {
156  public:
158  {}
159 
160  SubControlVolumeFace(const Intersection &intersection, int localNeighborIdx)
161  {
162  exteriorIdx_ = localNeighborIdx;
163 
164  normal_ = intersection.centerUnitOuterNormal();
165 
166  const auto &geometry = intersection.geometry();
167  integrationPos_ = geometry.center();
168  area_ = geometry.volume();
169  }
170 
175  int interiorIndex() const
176  {
177  // The local index of the control volume in the interior
178  // of a face of the stencil in the element centered finite
179  // volume discretization is always the "central"
180  // element. In this implementation this element always has
181  // index 0....
182  return 0;
183  }
184 
189  int exteriorIndex() const
190  { return exteriorIdx_; }
191 
196  const GlobalPosition &integrationPos() const
197  { return integrationPos_; }
198 
203  const WorldVector &normal() const
204  { return normal_; }
205 
209  Scalar area() const
210  { return area_; }
211 
212  private:
213  int interiorIdx_;
214  int exteriorIdx_;
215 
216  Scalar area_;
217 
218  GlobalPosition integrationPos_;
219  WorldVector normal_;
220  std::vector<Scalar> shapeValue_;
221  std::vector<WorldVector> shapeGradient_;
222  };
223 
224  EcfvStencil(const GridView &gridView)
225  : gridView_(gridView)
226  , elementMapper_(gridView)
227  { }
228 
229  void updateTopology(const Element &element)
230  {
231  auto isIt = gridView_.ibegin(element);
232  const auto &endIsIt = gridView_.iend(element);
233 
234 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
235  auto scv = SubControlVolume(element);
236  // add the "center" element of the stencil
237  subControlVolumes_.resize(0, scv);
238  subControlVolumes_.push_back(scv);
239  elements_.resize(0, element);
240  elements_.push_back(element);
241 #else
242  auto ePtr = ElementPointer(element);
243  auto scv = SubControlVolume(ePtr);
244  // add the "center" element of the stencil
245  subControlVolumes_.resize(0, scv);
246  subControlVolumes_.push_back(scv);
247  elements_.resize(0, ePtr);
248  elements_.push_back(ePtr);
249 #endif
250 
251  interiorFaces_.resize(0);
252  boundaryFaces_.resize(0);
253 
254  for (; isIt != endIsIt; ++isIt) {
255  const auto& intersection = *isIt;
256  // if the current intersection has a neighbor, add a
257  // degree of freedom and an internal face, else add a
258  // boundary face
259  if (intersection.neighbor()) {
260  elements_.push_back(intersection.outside());
261  subControlVolumes_.push_back(SubControlVolume(intersection.outside()));
262  interiorFaces_.push_back(SubControlVolumeFace(intersection, subControlVolumes_.size() - 1));
263  }
264  else {
265  boundaryFaces_.push_back(SubControlVolumeFace(intersection, - 10000));
266  }
267  }
268  }
269 
270  void update(const Element &element)
271  {
272  updateTopology(element);
273  }
274 
276  {
277  assert(false); // not yet implemented
278  }
279 
283  const Element &element() const
284  { return *elements_[0]; }
285 
290  const GridView &gridView() const
291  { return *gridView_; }
292 
297  int numDof() const
298  { return subControlVolumes_.size(); }
299 
309  int numPrimaryDof() const
310  { return 1; }
311 
316  int globalSpaceIndex(int dofIdx) const
317  {
318  assert(0 <= dofIdx && dofIdx < numDof());
319 
320 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
321  return elementMapper_.index(element(dofIdx));
322 #else
323  return elementMapper_.map(element(dofIdx));
324 #endif
325  }
326 
330  Dune::PartitionType partitionType(int dofIdx) const
331  { return elements_[dofIdx]->partitionType(); }
332 
340  const Element &element(int dofIdx = 0) const
341  {
342  assert(0 <= dofIdx && dofIdx < numDof());
343 
344 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
345  return elements_[dofIdx];
346 #else
347  return *elements_[dofIdx];
348 #endif
349  }
350 
355  const SubControlVolume &subControlVolume(int dofIdx) const
356  { return subControlVolumes_[dofIdx]; }
357 
361  int numInteriorFaces() const
362  { return interiorFaces_.size(); }
363 
368  const SubControlVolumeFace &interiorFace(int bfIdx) const
369  { return interiorFaces_[bfIdx]; }
370 
374  int numBoundaryFaces() const
375  { return boundaryFaces_.size(); }
376 
381  const SubControlVolumeFace &boundaryFace(int bfIdx) const
382  { return boundaryFaces_[bfIdx]; }
383 
384 private:
385  GridView gridView_;
386  ElementMapper elementMapper_;
387 
388 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
389  std::vector<Element> elements_;
390 #else
391  std::vector<ElementPointer> elements_;
392 #endif
393 
394  std::vector<SubControlVolume> subControlVolumes_;
395  std::vector<SubControlVolumeFace> interiorFaces_;
396  std::vector<SubControlVolumeFace> boundaryFaces_;
397 };
398 
399 } // namespace Ewoms
400 
401 
402 #endif
403 
void updateTopology(const Element &element)
Definition: ecfvstencil.hh:229
Represents the stencil (finite volume geometry) of a single element in the ECFV discretization.
Definition: ecfvstencil.hh:51
const SubControlVolumeFace & boundaryFace(int bfIdx) const
Returns the boundary face object belonging to a given boundary face index.
Definition: ecfvstencil.hh:381
EcfvStencil(const GridView &gridView)
Definition: ecfvstencil.hh:224
Quadrature geometry for quadrilaterals.
const SubControlVolumeFace & interiorFace(int bfIdx) const
Returns the face object belonging to a given face index in the interior of the domain.
Definition: ecfvstencil.hh:368
int numInteriorFaces() const
Returns the number of interior faces of the stencil.
Definition: ecfvstencil.hh:361
void updateCenterGradients()
Definition: ecfvstencil.hh:275
int exteriorIndex() const
Returns the local index of the degree of freedom to the face's outside.
Definition: ecfvstencil.hh:189
void update()
Definition: ecfvstencil.hh:100
int numPrimaryDof() const
Returns the number of degrees of freedom which are contained by within the current element...
Definition: ecfvstencil.hh:309
const GlobalPosition & center() const
The center of the sub-control volume.
Definition: ecfvstencil.hh:120
int numDof() const
Returns the number of degrees of freedom which the current element interacts with.
Definition: ecfvstencil.hh:297
const Element & element() const
Return the element to which the stencil refers.
Definition: ecfvstencil.hh:283
SubControlVolumeFace(const Intersection &intersection, int localNeighborIdx)
Definition: ecfvstencil.hh:160
Represents a sub-control volume.
Definition: ecfvstencil.hh:80
int globalSpaceIndex(int dofIdx) const
Return the global space index given the index of a degree of freedom.
Definition: ecfvstencil.hh:316
const GlobalPosition & globalPos() const
The global position associated with the sub-control volume.
Definition: ecfvstencil.hh:114
Element::Geometry LocalGeometry
Definition: ecfvstencil.hh:70
const WorldVector & normal() const
Returns the outer unit normal at the face's integration point.
Definition: ecfvstencil.hh:203
const LocalGeometry geometry() const
The geometry of the sub-control volume.
Definition: ecfvstencil.hh:136
Definition: baseauxiliarymodule.hh:35
const SubControlVolume & subControlVolume(int dofIdx) const
Returns the sub-control volume object belonging to a given degree of freedom.
Definition: ecfvstencil.hh:355
int interiorIndex() const
Returns the local index of the degree of freedom to the face's interior.
Definition: ecfvstencil.hh:175
const Element & element(int dofIdx=0) const
Return the element given the index of a degree of freedom.
Definition: ecfvstencil.hh:340
Scalar area() const
Returns the area [m^2] of the face.
Definition: ecfvstencil.hh:209
SubControlVolumeFace()
Definition: ecfvstencil.hh:157
Scalar volume() const
The volume [m^3] occupied by the sub-control volume.
Definition: ecfvstencil.hh:126
const GridView & gridView() const
Return the grid view of the element to which the stencil refers.
Definition: ecfvstencil.hh:290
Represents a face of a sub-control volume.
Definition: ecfvstencil.hh:154
void update(const Element &element)
Definition: ecfvstencil.hh:270
SubControlVolume(const ElementPointer &elementPtr)
Definition: ecfvstencil.hh:87
Dune::PartitionType partitionType(int dofIdx) const
Return partition type of a given degree of freedom.
Definition: ecfvstencil.hh:330
const GlobalPosition & integrationPos() const
Returns the global position of the face's integration point.
Definition: ecfvstencil.hh:196
void update(const ElementPointer &elementPtr)
Definition: ecfvstencil.hh:96
int numBoundaryFaces() const
Returns the number of boundary faces of the stencil.
Definition: ecfvstencil.hh:374