GridInterfaceEuler.hpp
Go to the documentation of this file.
1//===========================================================================
2//
3// File: GridInterfaceEuler.hpp
4//
5// Created: Mon Jun 15 12:53:38 2009
6//
7// Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8// Bård Skaflestad <bard.skaflestad@sintef.no>
9//
10// $Date$
11//
12// $Revision$
13//
14//===========================================================================
15
16/*
17 Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18 Copyright 2009, 2010 Statoil ASA.
19
20 This file is part of The Open Reservoir Simulator Project (OpenRS).
21
22 OpenRS is free software: you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation, either version 3 of the License, or
25 (at your option) any later version.
26
27 OpenRS is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License
33 along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
34*/
35
36#ifndef OPENRS_GRIDINTERFACEEULER_HEADER
37#define OPENRS_GRIDINTERFACEEULER_HEADER
38
39#include <dune/common/fvector.hh>
40#include <opm/core/utility/SparseTable.hpp>
41#include <opm/core/utility/StopWatch.hpp>
42#include <dune/grid/common/mcmgmapper.hh>
43#include <dune/grid/CpGrid.hpp> // How to avoid this? Needed for the explicit mapper specialization below.
44
45#include <boost/iterator/iterator_facade.hpp>
46#include <boost/scoped_ptr.hpp>
47
48#include <climits>
49#include <iostream>
50
51
52
53namespace Opm
54{
55
57 template<int dim>
59 bool contains(Dune::GeometryType gt) { return gt.dim() == dim; }
60 };
61
63 template <class DuneGrid>
65 {
66 typedef Dune::LeafMultipleCodimMultipleGeomTypeMapper<DuneGrid, AllCellsLayout> Type;
67 };
68
71 {
72 explicit CpGridCellMapper(const Dune::CpGrid&)
73 {
74 }
75 template<class EntityType>
76 int map (const EntityType& e) const
77 {
78 return e.index();
79 }
80 };
81
85 template <>
86 struct GICellMapper<Dune::CpGrid>
87 {
89 };
90
91
92 namespace GIE
93 {
94 template <class GridInterface, class EntityPointerType>
95 class Cell;
96
97 template <class GI>
98 class Face {
99 public:
100 typedef typename GI::DuneIntersectionIterator DuneIntersectionIter;
101 typedef typename GI::GridType::template Codim<0>::EntityPointer CellPtr;
102 typedef typename GI::GridType::ctype Scalar;
103 typedef Dune::FieldVector<Scalar, GI::GridType::dimension> Vector;
104 typedef Dune::FieldVector<Scalar, GI::GridType::dimension-1> LocalVector;
105 typedef int Index;
107
108 enum { BoundaryMarkerIndex = -999,
109 LocalEndIndex = INT_MAX };
110
112 : pgrid_(0), iter_(), local_index_(-1)
113 {
114 }
115
116 Face(const GI& grid,
117 const DuneIntersectionIter& it,
118 const Index loc_ind)
119 : pgrid_(&grid), iter_(it), local_index_(loc_ind)
120 {
121 }
122
126 Scalar area() const
127 {
128 return iter_->geometry().volume();
129 }
130
135 {
136 //return iter_->geometry().global(localCentroid());
137 return iter_->geometry().center();
138 }
139
144 {
145 //return iter_->unitOuterNormal(localCentroid());
146 return iter_->centerUnitOuterNormal();
147 }
148
152 bool boundary() const
153 {
154 return iter_->boundary();
155 }
156
160 int boundaryId() const
161 {
162 return iter_->boundaryId();
163 }
164
168 Cell cell() const
169 {
170 return Cell(*pgrid_, iter_->inside());
171 }
172
177 {
178 return pgrid_->mapper().map(*iter_->inside());
179 }
180
185 {
186 return Cell(*pgrid_, iter_->outside());
187 }
188
193 {
194 if (iter_->boundary()) {
195 return BoundaryMarkerIndex;
196 } else {
197 return pgrid_->mapper().map(*iter_->outside());
198 }
199 }
200
204 Index index() const
205 {
206 return pgrid_->faceIndex(cellIndex(), localIndex());
207 }
208
213 {
214 return local_index_;
215 }
216
221 {
222 return iter_->outside()->geometry().volume();
223 }
224
225 protected:
226 const GI* pgrid_;
229
230 private:
231// LocalVector localCentroid() const
232// {
233// typedef Dune::ReferenceElements<Scalar, GI::GridType::dimension-1> RefElems;
234// return RefElems::general(iter_->type()).position(0,0);
235// }
236 };
237
238
244 template <class GridInterface>
246 public boost::iterator_facade<FaceIterator<GridInterface>,
247 const Face<GridInterface>,
248 boost::forward_traversal_tag>,
249 public Face<GridInterface>
250 {
251 private:
253
254 public:
259
262 : FaceType()
263 {
264 }
265
277 FaceIterator(const GridInterface& grid,
278 const DuneIntersectionIter& it,
279 const int local_index)
280 : FaceType(grid, it, local_index)
281 {
282 }
283
286 {
287 return *this;
288 }
289
291 bool equal(const FaceIterator& other) const
292 {
293 // Note that we do not compare the local_index_ members,
294 // since they may or may not be equal for end iterators.
295 return FaceType::iter_ == other.FaceType::iter_;
296 }
297
300 {
303 }
304
306 bool operator<(const FaceIterator& other) const
307 {
308 if (FaceType::cellIndex() == other.FaceType::cellIndex()) {
309 return FaceType::localIndex() < other.FaceType::localIndex();
310 } else {
311 return FaceType::cellIndex() < other.FaceType::cellIndex();
312 }
313 }
314 };
315
316
317 template <class GridInterface, class EntityPointerType>
318 class Cell
319 {
320 public:
322 : pgrid_(0), iter_()
323 {
324 }
325 Cell(const GridInterface& grid,
326 const EntityPointerType& it)
327 : pgrid_(&grid), iter_(it)
328 {
329 }
331 typedef typename FaceIterator::Vector Vector;
332 typedef typename FaceIterator::Scalar Scalar;
333 typedef typename FaceIterator::Index Index;
334
336 {
337 return FaceIterator(*pgrid_, iter_->ileafbegin(), 0);
338 }
339
341 {
342 return FaceIterator(*pgrid_, iter_->ileafend(),
344 }
345
347 {
348 return iter_->geometry().volume();
349 }
350
352 {
353// typedef Dune::ReferenceElements<Scalar, GridInterface::GridType::dimension> RefElems;
354// Vector localpt
355// = RefElems::general(iter_->type()).position(0,0);
356// return iter_->geometry().global(localpt);
357 return iter_->geometry().center();
358 }
359
360 Index index() const
361 {
362 return pgrid_->mapper().map(*iter_);
363 }
364 protected:
365 const GridInterface* pgrid_;
366 EntityPointerType iter_;
367 };
368
369
370 template <class GridInterface>
372 : public boost::iterator_facade<CellIterator<GridInterface>,
373 const Cell<GridInterface,
374 typename GridInterface::GridType::template Codim<0>::LeafIterator>,
375 boost::forward_traversal_tag>,
376 public Cell<GridInterface, typename GridInterface::GridType::template Codim<0>::LeafIterator>
377 {
378 private:
379 typedef typename GridInterface::GridType::template Codim<0>::LeafIterator DuneCellIter;
381 public:
382 typedef typename CellType::Vector Vector;
383 typedef typename CellType::Scalar Scalar;
384 typedef typename CellType::Index Index;
385
386 CellIterator(const GridInterface& grid, DuneCellIter it)
387 : CellType(grid, it)
388 {
389 }
392 {
393 return *this;
394 }
396 bool equal(const CellIterator& other) const
397 {
398 return CellType::iter_ == other.CellType::iter_;
399 }
402 {
404 }
405 };
406
407 } // namespace GIE
408
409
410 template <class DuneGrid>
412 {
413 public:
414 typedef typename DuneGrid::LeafIntersectionIterator DuneIntersectionIterator;
415 typedef DuneGrid GridType;
418 typedef typename CellIterator::Vector Vector;
419 typedef typename CellIterator::Scalar Scalar;
420 typedef typename CellIterator::Index Index;
421
423
424 enum { Dimension = DuneGrid::dimension };
425
427 : pgrid_(0), num_faces_(0), max_faces_per_cell_(0)
428 {
429 }
430 explicit GridInterfaceEuler(const DuneGrid& grid, bool build_facemap = true)
431 : pgrid_(&grid), pmapper_(new Mapper(grid)), num_faces_(0), max_faces_per_cell_(0)
432 {
433 if (build_facemap) {
434 buildFaceIndices();
435 }
436 }
437 void init(const DuneGrid& grid, bool build_facemap = true)
438 {
439 pgrid_ = &grid;
440 pmapper_.reset(new Mapper(grid));
441 if (build_facemap) {
442 buildFaceIndices();
443 }
444 }
446 {
447 return CellIterator(*this, grid().template leafbegin<0>());
448 }
450 {
451 return CellIterator(*this, grid().template leafend<0>());
452 }
453 int numberOfCells() const
454 {
455 return grid().size(0);
456 }
457 int numberOfFaces() const
458 {
459 assert(num_faces_ != 0);
460 return num_faces_;
461 }
462 int maxFacesPerCell() const
463 {
464 assert(max_faces_per_cell_ != 0);
465 return max_faces_per_cell_;
466 }
467 const DuneGrid& grid() const
468 {
469 assert(pgrid_);
470 return *pgrid_;
471 }
472
473 // The following are primarily helpers for the implementation,
474 // perhaps they should be private?
475 const Mapper& mapper() const
476 {
477 assert (pmapper_);
478 return *pmapper_;
479 }
480 Index faceIndex(int cell_index, int local_face_index) const
481 {
482 assert(num_faces_ != 0);
483 return face_indices_[cell_index][local_face_index];
484 }
485 typedef Opm::SparseTable<int>::row_type Indices;
486 Indices faceIndices(int cell_index) const
487 {
488 assert(num_faces_ != 0);
489 return face_indices_[cell_index];
490 }
491 private:
492 const DuneGrid* pgrid_;
493 boost::scoped_ptr<Mapper> pmapper_;
494 int num_faces_;
495 int max_faces_per_cell_;
496 Opm::SparseTable<int> face_indices_;
497
498 void buildFaceIndices()
499 {
500#ifdef VERBOSE
501 std::cout << "Building unique face indices... " << std::flush;
502 Opm::time::StopWatch clock;
503 clock.start();
504#endif
505 typedef CellIterator CI;
506 typedef typename CI::FaceIterator FI;
507
508 // We build the actual cell to face mapping in two passes.
509 // [code mostly lifted from IncompFlowSolverHybrid::enumerateGridDof(),
510 // but with a twist: This code builds a mapping from cells in index
511 // order to unique face numbers, while the mapping built in the
512 // enumerateGridDof() method was ordered by cell iterator order]
513
514 // Allocate and reserve structures.
515 const int nc = numberOfCells();
516 std::vector<int> cell(nc, -1);
517 std::vector<int> num_faces(nc); // In index order.
518 std::vector<int> fpos; fpos .reserve(nc + 1);
519 std::vector<int> num_cf; num_cf.reserve(nc); // In iterator order.
520 std::vector<int> faces ;
521
522 // First pass: enumerate internal faces.
523 int cellno = 0; fpos.push_back(0);
524 int tot_ncf = 0, tot_ncf2 = 0, max_ncf = 0;
525 for (CI c = cellbegin(); c != cellend(); ++c, ++cellno) {
526 const int c0 = c->index();
527 assert((0 <= c0) && (c0 < nc) && (cell[c0] == -1));
528 cell[c0] = cellno;
529 num_cf.push_back(0);
530 int& ncf = num_cf.back();
531 for (FI f = c->facebegin(); f != c-> faceend(); ++f) {
532 if (!f->boundary()) {
533 const int c1 = f->neighbourCellIndex();
534 assert((0 <= c1) && (c1 < nc) && (c1 != c0));
535
536 if (cell[c1] == -1) {
537 // Previously undiscovered internal face.
538 faces.push_back(c1);
539 }
540 }
541 ++ncf;
542 }
543 num_faces[c0] = ncf;
544 fpos.push_back(int(faces.size()));
545 max_ncf = std::max(max_ncf, ncf);
546 tot_ncf += ncf;
547 tot_ncf2 += ncf * ncf;
548 }
549 assert(cellno == nc);
550
551 // Build cumulative face sizes enabling direct insertion of
552 // face indices into cfdata later.
553 std::vector<int> cumul_num_faces(numberOfCells() + 1);
554 cumul_num_faces[0] = 0;
555 std::partial_sum(num_faces.begin(), num_faces.end(), cumul_num_faces.begin() + 1);
556
557 // Avoid (most) allocation(s) inside 'c' loop.
558 std::vector<int> l2g;
559 l2g.reserve(max_ncf);
560 std::vector<double> cfdata(tot_ncf);
561 int total_num_faces = int(faces.size());
562
563 // Second pass: build cell-to-face mapping, including boundary.
564 typedef std::vector<int>::iterator VII;
565 for (CI c = cellbegin(); c != cellend(); ++c) {
566 const int c0 = c->index();
567 assert ((0 <= c0 ) && ( c0 < nc) &&
568 (0 <= cell[c0]) && (cell[c0] < nc));
569 const int ncf = num_cf[cell[c0]];
570 l2g.resize(ncf, 0);
571 for (FI f = c->facebegin(); f != c->faceend(); ++f) {
572 if (f->boundary()) {
573 // External, not counted before. Add new face...
574 l2g[f->localIndex()] = total_num_faces++;
575 } else {
576 // Internal face. Need to determine during
577 // traversal of which cell we discovered this
578 // face first, and extract the face number
579 // from the 'faces' table range of that cell.
580
581 // Note: std::find() below is potentially
582 // *VERY* expensive (e.g., large number of
583 // seeks in moderately sized data in case of
584 // faulted cells).
585 const int c1 = f->neighbourCellIndex();
586 assert ((0 <= c1 ) && ( c1 < nc) &&
587 (0 <= cell[c1]) && (cell[c1] < nc));
588
589 int t = c0, seek = c1;
590 if (cell[seek] < cell[t])
591 std::swap(t, seek);
592 int s = fpos[cell[t]], e = fpos[cell[t] + 1];
593 VII p = std::find(faces.begin() + s, faces.begin() + e, seek);
594 assert(p != faces.begin() + e);
595 l2g[f->localIndex()] = p - faces.begin();
596 }
597 }
598 assert(int(l2g.size()) == num_faces[c0]);
599 std::copy(l2g.begin(), l2g.end(), cfdata.begin() + cumul_num_faces[c0]);
600 }
601 num_faces_ = total_num_faces;
602 max_faces_per_cell_ = max_ncf;
603 face_indices_.assign(cfdata.begin(), cfdata.end(),
604 num_faces.begin(), num_faces.end());
605
606#ifdef VERBOSE
607 clock.stop();
608 double elapsed = clock.secsSinceStart();
609 std::cout << "done. Time elapsed: " << elapsed << std::endl;
610#endif
611 }
612
613 };
614
615
616
617} // namespace Opm
618
619
620#endif // OPENRS_GRIDINTERFACEEULER_HEADER
Definition: GridInterfaceEuler.hpp:377
const CellIterator & dereference() const
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:391
CellType::Vector Vector
Definition: GridInterfaceEuler.hpp:382
CellIterator(const GridInterface &grid, DuneCellIter it)
Definition: GridInterfaceEuler.hpp:386
CellType::Scalar Scalar
Definition: GridInterfaceEuler.hpp:383
bool equal(const CellIterator &other) const
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:396
void increment()
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:401
CellType::Index Index
Definition: GridInterfaceEuler.hpp:384
Definition: GridInterfaceEuler.hpp:319
Scalar volume() const
Definition: GridInterfaceEuler.hpp:346
Vector centroid() const
Definition: GridInterfaceEuler.hpp:351
FaceIterator faceend() const
Definition: GridInterfaceEuler.hpp:340
Cell()
Definition: GridInterfaceEuler.hpp:321
FaceIterator::Scalar Scalar
Definition: GridInterfaceEuler.hpp:332
Cell(const GridInterface &grid, const EntityPointerType &it)
Definition: GridInterfaceEuler.hpp:325
FaceIterator::Index Index
Definition: GridInterfaceEuler.hpp:333
Index index() const
Definition: GridInterfaceEuler.hpp:360
FaceIterator facebegin() const
Definition: GridInterfaceEuler.hpp:335
FaceIterator::Vector Vector
Definition: GridInterfaceEuler.hpp:331
EntityPointerType iter_
Definition: GridInterfaceEuler.hpp:366
const GridInterface * pgrid_
Definition: GridInterfaceEuler.hpp:365
GIE::FaceIterator< GridInterface > FaceIterator
Definition: GridInterfaceEuler.hpp:330
Intersection (face) iterator for solver-near grid interface.
Definition: GridInterfaceEuler.hpp:250
bool equal(const FaceIterator &other) const
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:291
void increment()
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:299
Face< GridInterface >::DuneIntersectionIter DuneIntersectionIter
Type of low-level intersection iterator. Copied from the Dune grid.
Definition: GridInterfaceEuler.hpp:258
bool operator<(const FaceIterator &other) const
Gives an ordering of intersectionIterators.
Definition: GridInterfaceEuler.hpp:306
const FaceIterator & dereference() const
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:285
FaceIterator(const GridInterface &grid, const DuneIntersectionIter &it, const int local_index)
Constructor.
Definition: GridInterfaceEuler.hpp:277
FaceIterator()
Default constructor.
Definition: GridInterfaceEuler.hpp:261
Definition: GridInterfaceEuler.hpp:98
Dune::FieldVector< Scalar, GI::GridType::dimension-1 > LocalVector
Definition: GridInterfaceEuler.hpp:104
Index local_index_
Definition: GridInterfaceEuler.hpp:228
const GI * pgrid_
Definition: GridInterfaceEuler.hpp:226
Vector normal() const
Definition: GridInterfaceEuler.hpp:143
Vector centroid() const
Definition: GridInterfaceEuler.hpp:134
GI::DuneIntersectionIterator DuneIntersectionIter
Definition: GridInterfaceEuler.hpp:100
Face(const GI &grid, const DuneIntersectionIter &it, const Index loc_ind)
Definition: GridInterfaceEuler.hpp:116
GI::GridType::template Codim< 0 >::EntityPointer CellPtr
Definition: GridInterfaceEuler.hpp:101
Index neighbourCellIndex() const
Definition: GridInterfaceEuler.hpp:192
DuneIntersectionIter iter_
Definition: GridInterfaceEuler.hpp:227
bool boundary() const
Definition: GridInterfaceEuler.hpp:152
int Index
Definition: GridInterfaceEuler.hpp:105
@ LocalEndIndex
Definition: GridInterfaceEuler.hpp:109
@ BoundaryMarkerIndex
Definition: GridInterfaceEuler.hpp:108
Cell cell() const
Definition: GridInterfaceEuler.hpp:168
GIE::Cell< GI, CellPtr > Cell
Definition: GridInterfaceEuler.hpp:106
Index cellIndex() const
Definition: GridInterfaceEuler.hpp:176
GI::GridType::ctype Scalar
Definition: GridInterfaceEuler.hpp:102
Cell neighbourCell() const
Definition: GridInterfaceEuler.hpp:184
int boundaryId() const
Definition: GridInterfaceEuler.hpp:160
Index localIndex() const
Definition: GridInterfaceEuler.hpp:212
Scalar neighbourCellVolume() const
Definition: GridInterfaceEuler.hpp:220
Face()
Definition: GridInterfaceEuler.hpp:111
Dune::FieldVector< Scalar, GI::GridType::dimension > Vector
Definition: GridInterfaceEuler.hpp:103
Scalar area() const
Definition: GridInterfaceEuler.hpp:126
Index index() const
Definition: GridInterfaceEuler.hpp:204
Definition: GridInterfaceEuler.hpp:412
int numberOfFaces() const
Definition: GridInterfaceEuler.hpp:457
Opm::SparseTable< int >::row_type Indices
Definition: GridInterfaceEuler.hpp:485
void init(const DuneGrid &grid, bool build_facemap=true)
Definition: GridInterfaceEuler.hpp:437
Indices faceIndices(int cell_index) const
Definition: GridInterfaceEuler.hpp:486
const DuneGrid & grid() const
Definition: GridInterfaceEuler.hpp:467
@ Dimension
Definition: GridInterfaceEuler.hpp:424
const Mapper & mapper() const
Definition: GridInterfaceEuler.hpp:475
GridInterfaceEuler< DuneGrid > InterfaceType
Definition: GridInterfaceEuler.hpp:416
CellIterator::Index Index
Definition: GridInterfaceEuler.hpp:420
CellIterator cellend() const
Definition: GridInterfaceEuler.hpp:449
GIE::CellIterator< InterfaceType > CellIterator
Definition: GridInterfaceEuler.hpp:417
GridInterfaceEuler()
Definition: GridInterfaceEuler.hpp:426
CellIterator cellbegin() const
Definition: GridInterfaceEuler.hpp:445
GICellMapper< DuneGrid >::Type Mapper
Definition: GridInterfaceEuler.hpp:422
CellIterator::Scalar Scalar
Definition: GridInterfaceEuler.hpp:419
Index faceIndex(int cell_index, int local_face_index) const
Definition: GridInterfaceEuler.hpp:480
CellIterator::Vector Vector
Definition: GridInterfaceEuler.hpp:418
int numberOfCells() const
Definition: GridInterfaceEuler.hpp:453
GridInterfaceEuler(const DuneGrid &grid, bool build_facemap=true)
Definition: GridInterfaceEuler.hpp:430
DuneGrid GridType
Definition: GridInterfaceEuler.hpp:415
DuneGrid::LeafIntersectionIterator DuneIntersectionIterator
Definition: GridInterfaceEuler.hpp:414
int maxFacesPerCell() const
Definition: GridInterfaceEuler.hpp:462
Definition: BlackoilFluid.hpp:32
General cell layout.
Definition: GridInterfaceEuler.hpp:58
bool contains(Dune::GeometryType gt)
Definition: GridInterfaceEuler.hpp:59
A mapper for Dune::CpGrid cells only.
Definition: GridInterfaceEuler.hpp:71
int map(const EntityType &e) const
Definition: GridInterfaceEuler.hpp:76
CpGridCellMapper(const Dune::CpGrid &)
Definition: GridInterfaceEuler.hpp:72
CpGridCellMapper Type
Definition: GridInterfaceEuler.hpp:88
Mapper for general grids.
Definition: GridInterfaceEuler.hpp:65
Dune::LeafMultipleCodimMultipleGeomTypeMapper< DuneGrid, AllCellsLayout > Type
Definition: GridInterfaceEuler.hpp:66