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 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
28#ifndef EWOMS_ECFV_STENCIL_HH
29#define EWOMS_ECFV_STENCIL_HH
30
32
33#include <opm/material/common/ConditionalStorage.hpp>
34
35#include <dune/grid/common/mcmgmapper.hh>
36#include <dune/grid/common/intersectioniterator.hh>
37#include <dune/geometry/type.hh>
38#include <dune/common/fvector.hh>
39#include <dune/common/version.hh>
40#include <opm/common/ErrorMacros.hpp>
41#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
42
43#include <vector>
44
45namespace Opm {
56template <class Scalar,
57 class GridView,
58 bool needFaceIntegrationPos = true,
59 bool needFaceNormal = true>
61{
62 enum { dimWorld = GridView::dimensionworld };
63
64 using CoordScalar = typename GridView::ctype;
65 using Intersection = typename GridView::Intersection;
66 using Element = typename GridView::template Codim<0>::Entity;
67
68 using ElementMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
69
70 using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
71
72 using WorldVector = Dune::FieldVector<Scalar, dimWorld>;
73
74public:
75 using Entity = Element ;
76 using Mapper = ElementMapper ;
77
78 using LocalGeometry = typename Element::Geometry;
79
89 {
90 public:
91 // default construct an uninitialized object.
92 // this is only here because std::vector needs it...
94 {}
95
96 SubControlVolume(const Element& element)
97 : element_(element)
98 { update(); }
99
100 void update(const Element& element)
101 { element_ = element; }
102
103 void update()
104 { }
105
109 decltype(auto) globalPos() const
110 { return element_.geometry().center(); }
111
115 decltype(auto) center() const
116 { return element_.geometry().center(); }
117
121 Scalar volume() const
122 { return element_.geometry().volume(); }
123
128 { return element_.geometry(); }
129
134 { return element_.geometryInFather(); }
135
136 private:
137 Element element_;
138 };
139
143 template <bool needIntegrationPos, bool needNormal>
145 {
146 public:
148 {}
149
150 EcfvSubControlVolumeFace(const Intersection& intersection, unsigned localNeighborIdx)
151 {
152 exteriorIdx_ = static_cast<unsigned short>(localNeighborIdx);
153
154 if (needNormal)
155 (*normal_) = intersection.centerUnitOuterNormal();
156 const auto& geometry = intersection.geometry();
157 if (needIntegrationPos)
158 (*integrationPos_) = geometry.center();
159 area_ = geometry.volume();
160 // TODO: facedir_ = intersection.boundaryId(); // This did not compile for some reason
161 // using indexInInside() as in ecltransmissibility.cc instead
162 // Note that indexInInside() returns -1 for NNC faces, that's the reason we
163 // cannot convert directly to a FaceDir::DirEnum (see FaceDir.hpp)
164 dirId_ = intersection.indexInInside(); // Legal values: -1, 0, 1, 2, 3, 4, 5
165 }
166
171 unsigned short interiorIndex() const
172 {
173 // The local index of the control volume in the interior
174 // of a face of the stencil in the element centered finite
175 // volume discretization is always the "central"
176 // element. In this implementation this element always has
177 // index 0....
178 return 0;
179 }
180
185 unsigned short exteriorIndex() const
186 { return exteriorIdx_; }
187
192 const GlobalPosition& integrationPos() const
193 { return *integrationPos_; }
194
199 const WorldVector& normal() const
200 { return *normal_; }
201
205 Scalar area() const
206 { return area_; }
207
214 int dirId() const
215 {
216 return dirId_;
217 }
218
222 FaceDir::DirEnum faceDirFromDirId() const
223 {
224 using Dir = FaceDir::DirEnum;
225 if (dirId_ == -1) {
226 OPM_THROW(std::runtime_error, "NNC faces does not have a face id");
227 }
228 switch(dirId_) {
229 case 0:
230 case 1:
231 return Dir::XPlus;
232 case 2:
233 case 3:
234 return Dir::YPlus;
235 case 4:
236 case 5:
237 return Dir::ZPlus;
238 default:
239 OPM_THROW(std::runtime_error,
240 "Unexpected face id" + std::to_string(dirId_));
241 }
242 }
243
244 private:
245 ConditionalStorage<needIntegrationPos, GlobalPosition> integrationPos_;
246 ConditionalStorage<needNormal, WorldVector> normal_;
247 Scalar area_;
248 int dirId_;
249
250 unsigned short exteriorIdx_;
251 };
252
254 using BoundaryFace = EcfvSubControlVolumeFace</*needFaceIntegrationPos=*/true, needFaceNormal>;
255
256 EcfvStencil(const GridView& gridView, const Mapper& mapper)
258 , elementMapper_(mapper)
259 {
260 // try to ensure that the mapper passed indeed maps elements
261 assert(int(gridView.size(/*codim=*/0)) == int(elementMapper_.size()));
262 }
263
264 void updateTopology(const Element& element)
265 {
266 auto isIt = gridView_.ibegin(element);
267 const auto& endIsIt = gridView_.iend(element);
268
269 // add the "center" element of the stencil
270 subControlVolumes_.clear();
271 subControlVolumes_.emplace_back(/*SubControlVolume(*/element/*)*/);
272 elements_.clear();
273 elements_.emplace_back(element);
274
275 interiorFaces_.clear();
276 boundaryFaces_.clear();
277
278 for (; isIt != endIsIt; ++isIt) {
279 const auto& intersection = *isIt;
280 // if the current intersection has a neighbor, add a
281 // degree of freedom and an internal face, else add a
282 // boundary face
283 if (intersection.neighbor()) {
284 elements_.emplace_back( intersection.outside() );
285 subControlVolumes_.emplace_back(/*SubControlVolume(*/elements_.back()/*)*/);
286 interiorFaces_.emplace_back(/*SubControlVolumeFace(*/intersection, subControlVolumes_.size() - 1/*)*/);
287 }
288 else {
289 boundaryFaces_.emplace_back(/*SubControlVolumeFace(*/intersection, - 10000/*)*/);
290 }
291 }
292 }
293
294 void updatePrimaryTopology(const Element& element)
295 {
296 // add the "center" element of the stencil
297 subControlVolumes_.clear();
298 subControlVolumes_.emplace_back(/*SubControlVolume(*/element/*)*/);
299 elements_.clear();
300 elements_.emplace_back(element);
301 }
302
303 void update(const Element& element)
304 {
306 }
307
309 {
310 assert(false); // not yet implemented
311 }
312
316 const Element& element() const
317 { return element( 0 ); }
318
323 const GridView& gridView() const
324 { return *gridView_; }
325
330 size_t numDof() const
331 { return subControlVolumes_.size(); }
332
342 size_t numPrimaryDof() const
343 { return 1; }
344
349 unsigned globalSpaceIndex(unsigned dofIdx) const
350 {
351 assert(dofIdx < numDof());
352
353 return static_cast<unsigned>(elementMapper_.index(element(dofIdx)));
354 }
355
359 Dune::PartitionType partitionType(unsigned dofIdx) const
360 { return elements_[dofIdx]->partitionType(); }
361
369 const Element& element(unsigned dofIdx) const
370 {
371 assert(dofIdx < numDof());
372
373 return elements_[dofIdx];
374 }
375
380 const Entity& entity(unsigned dofIdx) const
381 {
382 return element( dofIdx );
383 }
384
389 const SubControlVolume& subControlVolume(unsigned dofIdx) const
390 { return subControlVolumes_[dofIdx]; }
391
395 size_t numInteriorFaces() const
396 { return interiorFaces_.size(); }
397
402 const SubControlVolumeFace& interiorFace(unsigned faceIdx) const
403 { return interiorFaces_[faceIdx]; }
404
408 size_t numBoundaryFaces() const
409 { return boundaryFaces_.size(); }
410
415 const BoundaryFace& boundaryFace(unsigned bfIdx) const
416 { return boundaryFaces_[bfIdx]; }
417
418protected:
419 const GridView& gridView_;
420 const ElementMapper& elementMapper_;
421
422 std::vector<Element> elements_;
423 std::vector<SubControlVolume> subControlVolumes_;
424 std::vector<SubControlVolumeFace> interiorFaces_;
425 std::vector<BoundaryFace> boundaryFaces_;
426};
427
428} // namespace Opm
429
430
431#endif
432
Represents a face of a sub-control volume.
Definition: ecfvstencil.hh:145
const GlobalPosition & integrationPos() const
Returns the global position of the face's integration point.
Definition: ecfvstencil.hh:192
EcfvSubControlVolumeFace()
Definition: ecfvstencil.hh:147
unsigned short interiorIndex() const
Returns the local index of the degree of freedom to the face's interior.
Definition: ecfvstencil.hh:171
unsigned short exteriorIndex() const
Returns the local index of the degree of freedom to the face's outside.
Definition: ecfvstencil.hh:185
const WorldVector & normal() const
Returns the outer unit normal at the face's integration point.
Definition: ecfvstencil.hh:199
FaceDir::DirEnum faceDirFromDirId() const
Returns the direction of the face.
Definition: ecfvstencil.hh:222
Scalar area() const
Returns the area [m^2] of the face.
Definition: ecfvstencil.hh:205
int dirId() const
Returns the direction id of the face w.r.t the cell.
Definition: ecfvstencil.hh:214
EcfvSubControlVolumeFace(const Intersection &intersection, unsigned localNeighborIdx)
Definition: ecfvstencil.hh:150
Represents a sub-control volume.
Definition: ecfvstencil.hh:89
const LocalGeometry geometry() const
The geometry of the sub-control volume.
Definition: ecfvstencil.hh:127
Scalar volume() const
The volume [m^3] occupied by the sub-control volume.
Definition: ecfvstencil.hh:121
void update(const Element &element)
Definition: ecfvstencil.hh:100
SubControlVolume(const Element &element)
Definition: ecfvstencil.hh:96
const LocalGeometry localGeometry() const
Geometry of the sub-control volume relative to parent.
Definition: ecfvstencil.hh:133
SubControlVolume()
Definition: ecfvstencil.hh:93
decltype(auto) center() const
The center of the sub-control volume.
Definition: ecfvstencil.hh:115
decltype(auto) globalPos() const
The global position associated with the sub-control volume.
Definition: ecfvstencil.hh:109
void update()
Definition: ecfvstencil.hh:103
Represents the stencil (finite volume geometry) of a single element in the ECFV discretization.
Definition: ecfvstencil.hh:61
const SubControlVolumeFace & interiorFace(unsigned faceIdx) const
Returns the face object belonging to a given face index in the interior of the domain.
Definition: ecfvstencil.hh:402
std::vector< BoundaryFace > boundaryFaces_
Definition: ecfvstencil.hh:425
const BoundaryFace & boundaryFace(unsigned bfIdx) const
Returns the boundary face object belonging to a given boundary face index.
Definition: ecfvstencil.hh:415
const Element & element(unsigned dofIdx) const
Return the element given the index of a degree of freedom.
Definition: ecfvstencil.hh:369
std::vector< SubControlVolumeFace > interiorFaces_
Definition: ecfvstencil.hh:424
size_t numPrimaryDof() const
Returns the number of degrees of freedom which are contained by within the current element.
Definition: ecfvstencil.hh:342
EcfvStencil(const GridView &gridView, const Mapper &mapper)
Definition: ecfvstencil.hh:256
const Element & element() const
Return the element to which the stencil refers.
Definition: ecfvstencil.hh:316
const Entity & entity(unsigned dofIdx) const
Return the entity given the index of a degree of freedom.
Definition: ecfvstencil.hh:380
std::vector< SubControlVolume > subControlVolumes_
Definition: ecfvstencil.hh:423
size_t numBoundaryFaces() const
Returns the number of boundary faces of the stencil.
Definition: ecfvstencil.hh:408
void updateTopology(const Element &element)
Definition: ecfvstencil.hh:264
unsigned globalSpaceIndex(unsigned dofIdx) const
Return the global space index given the index of a degree of freedom.
Definition: ecfvstencil.hh:349
Element Entity
Definition: ecfvstencil.hh:75
typename Element::Geometry LocalGeometry
Definition: ecfvstencil.hh:78
void update(const Element &element)
Definition: ecfvstencil.hh:303
ElementMapper Mapper
Definition: ecfvstencil.hh:76
const GridView & gridView() const
Return the grid view of the element to which the stencil refers.
Definition: ecfvstencil.hh:323
const ElementMapper & elementMapper_
Definition: ecfvstencil.hh:420
void updateCenterGradients()
Definition: ecfvstencil.hh:308
size_t numInteriorFaces() const
Returns the number of interior faces of the stencil.
Definition: ecfvstencil.hh:395
Dune::PartitionType partitionType(unsigned dofIdx) const
Return partition type of a given degree of freedom.
Definition: ecfvstencil.hh:359
void updatePrimaryTopology(const Element &element)
Definition: ecfvstencil.hh:294
size_t numDof() const
Returns the number of degrees of freedom which the current element interacts with.
Definition: ecfvstencil.hh:330
std::vector< Element > elements_
Definition: ecfvstencil.hh:422
const SubControlVolume & subControlVolume(unsigned dofIdx) const
Returns the sub-control volume object belonging to a given degree of freedom.
Definition: ecfvstencil.hh:389
const GridView & gridView_
Definition: ecfvstencil.hh:419
Definition: blackoilboundaryratevector.hh:37