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 
53 namespace Opm
54 {
55 
57  template<int dim>
58  struct AllCellsLayout {
59  bool contains(Dune::GeometryType gt) { return gt.dim() == dim; }
60  };
61 
63  template <class DuneGrid>
64  struct GICellMapper
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 
134  Vector centroid() const
135  {
136  //return iter_->geometry().global(localCentroid());
137  return iter_->geometry().center();
138  }
139 
143  Vector normal() const
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 
176  Index cellIndex() const
177  {
178  return pgrid_->mapper().map(*iter_->inside());
179  }
180 
184  Cell neighbourCell() const
185  {
186  return Cell(*pgrid_, iter_->outside());
187  }
188 
192  Index neighbourCellIndex() const
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 
212  Index localIndex() const
213  {
214  return local_index_;
215  }
216 
220  Scalar neighbourCellVolume() const
221  {
222  return iter_->outside()->geometry().volume();
223  }
224 
225  protected:
226  const GI* pgrid_;
227  DuneIntersectionIter iter_;
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>
245  class FaceIterator :
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 
285  const FaceIterator& dereference() const
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 
299  void increment()
300  {
301  ++FaceType::iter_;
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 
335  FaceIterator facebegin() const
336  {
337  return FaceIterator(*pgrid_, iter_->ileafbegin(), 0);
338  }
339 
340  FaceIterator faceend() const
341  {
342  return FaceIterator(*pgrid_, iter_->ileafend(),
344  }
345 
346  Scalar volume() const
347  {
348  return iter_->geometry().volume();
349  }
350 
351  Vector centroid() const
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  }
391  const CellIterator& dereference() const
392  {
393  return *this;
394  }
396  bool equal(const CellIterator& other) const
397  {
398  return CellType::iter_ == other.CellType::iter_;
399  }
401  void increment()
402  {
403  ++CellType::iter_;
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  }
445  CellIterator cellbegin() const
446  {
447  return CellIterator(*this, grid().template leafbegin<0>());
448  }
449  CellIterator cellend() const
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
GridInterfaceEuler< DuneGrid > InterfaceType
Definition: GridInterfaceEuler.hpp:416
bool operator<(const FaceIterator &other) const
Gives an ordering of intersectionIterators.
Definition: GridInterfaceEuler.hpp:306
CpGridCellMapper Type
Definition: GridInterfaceEuler.hpp:88
FaceIterator faceend() const
Definition: GridInterfaceEuler.hpp:340
GIE::CellIterator< InterfaceType > CellIterator
Definition: GridInterfaceEuler.hpp:417
Index cellIndex() const
Definition: GridInterfaceEuler.hpp:176
Vector normal() const
Definition: GridInterfaceEuler.hpp:143
Definition: GridInterfaceEuler.hpp:109
Definition: GridInterfaceEuler.hpp:98
Definition: BlackoilFluid.hpp:31
void init(const DuneGrid &grid, bool build_facemap=true)
Definition: GridInterfaceEuler.hpp:437
const DuneGrid & grid() const
Definition: GridInterfaceEuler.hpp:467
const GI * pgrid_
Definition: GridInterfaceEuler.hpp:226
CellIterator cellend() const
Definition: GridInterfaceEuler.hpp:449
int numberOfCells() const
Definition: GridInterfaceEuler.hpp:453
int map(const EntityType &e) const
Definition: GridInterfaceEuler.hpp:76
GI::GridType::ctype Scalar
Definition: GridInterfaceEuler.hpp:102
bool boundary() const
Definition: GridInterfaceEuler.hpp:152
Cell()
Definition: GridInterfaceEuler.hpp:321
void increment()
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:401
GI::GridType::template Codim< 0 >::EntityPointer CellPtr
Definition: GridInterfaceEuler.hpp:101
const CellIterator & dereference() const
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:391
CellType::Scalar Scalar
Definition: GridInterfaceEuler.hpp:383
void increment()
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:299
Index index() const
Definition: GridInterfaceEuler.hpp:360
Index index() const
Definition: GridInterfaceEuler.hpp:204
CellIterator cellbegin() const
Definition: GridInterfaceEuler.hpp:445
Index localIndex() const
Definition: GridInterfaceEuler.hpp:212
FaceIterator facebegin() const
Definition: GridInterfaceEuler.hpp:335
const FaceIterator & dereference() const
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:285
GIE::FaceIterator< GridInterface > FaceIterator
Definition: GridInterfaceEuler.hpp:330
General cell layout.
Definition: GridInterfaceEuler.hpp:58
CellIterator::Index Index
Definition: GridInterfaceEuler.hpp:420
EntityPointerType iter_
Definition: GridInterfaceEuler.hpp:366
FaceIterator()
Default constructor.
Definition: GridInterfaceEuler.hpp:261
Definition: GridInterfaceEuler.hpp:108
GridInterfaceEuler(const DuneGrid &grid, bool build_facemap=true)
Definition: GridInterfaceEuler.hpp:430
Index neighbourCellIndex() const
Definition: GridInterfaceEuler.hpp:192
Index local_index_
Definition: GridInterfaceEuler.hpp:228
Cell neighbourCell() const
Definition: GridInterfaceEuler.hpp:184
const Mapper & mapper() const
Definition: GridInterfaceEuler.hpp:475
GridInterfaceEuler()
Definition: GridInterfaceEuler.hpp:426
Cell(const GridInterface &grid, const EntityPointerType &it)
Definition: GridInterfaceEuler.hpp:325
FaceIterator::Index Index
Definition: GridInterfaceEuler.hpp:333
Definition: GridInterfaceEuler.hpp:95
Face()
Definition: GridInterfaceEuler.hpp:111
Scalar area() const
Definition: GridInterfaceEuler.hpp:126
CellIterator::Scalar Scalar
Definition: GridInterfaceEuler.hpp:419
Intersection (face) iterator for solver-near grid interface.
Definition: GridInterfaceEuler.hpp:245
GICellMapper< DuneGrid >::Type Mapper
Definition: GridInterfaceEuler.hpp:422
int numberOfFaces() const
Definition: GridInterfaceEuler.hpp:457
Definition: GridInterfaceEuler.hpp:411
Definition: GridInterfaceEuler.hpp:424
FaceIterator(const GridInterface &grid, const DuneIntersectionIter &it, const int local_index)
Constructor.
Definition: GridInterfaceEuler.hpp:277
Face< GridInterface >::DuneIntersectionIter DuneIntersectionIter
Type of low-level intersection iterator. Copied from the Dune grid.
Definition: GridInterfaceEuler.hpp:258
int boundaryId() const
Definition: GridInterfaceEuler.hpp:160
Scalar neighbourCellVolume() const
Definition: GridInterfaceEuler.hpp:220
int maxFacesPerCell() const
Definition: GridInterfaceEuler.hpp:462
Dune::FieldVector< Scalar, GI::GridType::dimension-1 > LocalVector
Definition: GridInterfaceEuler.hpp:104
Vector centroid() const
Definition: GridInterfaceEuler.hpp:351
Dune::FieldVector< Scalar, GI::GridType::dimension > Vector
Definition: GridInterfaceEuler.hpp:103
CellType::Vector Vector
Definition: GridInterfaceEuler.hpp:382
Cell cell() const
Definition: GridInterfaceEuler.hpp:168
DuneGrid GridType
Definition: GridInterfaceEuler.hpp:415
const GridInterface * pgrid_
Definition: GridInterfaceEuler.hpp:365
FaceIterator::Vector Vector
Definition: GridInterfaceEuler.hpp:331
CpGridCellMapper(const Dune::CpGrid &)
Definition: GridInterfaceEuler.hpp:72
FaceIterator::Scalar Scalar
Definition: GridInterfaceEuler.hpp:332
A mapper for Dune::CpGrid cells only.
Definition: GridInterfaceEuler.hpp:70
bool equal(const FaceIterator &other) const
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:291
int Index
Definition: GridInterfaceEuler.hpp:105
Dune::LeafMultipleCodimMultipleGeomTypeMapper< DuneGrid, AllCellsLayout > Type
Definition: GridInterfaceEuler.hpp:66
CellIterator(const GridInterface &grid, DuneCellIter it)
Definition: GridInterfaceEuler.hpp:386
bool equal(const CellIterator &other) const
Used by iterator facade.
Definition: GridInterfaceEuler.hpp:396
DuneGrid::LeafIntersectionIterator DuneIntersectionIterator
Definition: GridInterfaceEuler.hpp:414
bool contains(Dune::GeometryType gt)
Definition: GridInterfaceEuler.hpp:59
GIE::Cell< GI, CellPtr > Cell
Definition: GridInterfaceEuler.hpp:106
Indices faceIndices(int cell_index) const
Definition: GridInterfaceEuler.hpp:486
CellType::Index Index
Definition: GridInterfaceEuler.hpp:384
Definition: GridInterfaceEuler.hpp:371
CellIterator::Vector Vector
Definition: GridInterfaceEuler.hpp:418
GI::DuneIntersectionIterator DuneIntersectionIter
Definition: GridInterfaceEuler.hpp:100
Vector centroid() const
Definition: GridInterfaceEuler.hpp:134
Face(const GI &grid, const DuneIntersectionIter &it, const Index loc_ind)
Definition: GridInterfaceEuler.hpp:116
Mapper for general grids.
Definition: GridInterfaceEuler.hpp:64
DuneIntersectionIter iter_
Definition: GridInterfaceEuler.hpp:227
Scalar volume() const
Definition: GridInterfaceEuler.hpp:346
Opm::SparseTable< int >::row_type Indices
Definition: GridInterfaceEuler.hpp:485
Index faceIndex(int cell_index, int local_face_index) const
Definition: GridInterfaceEuler.hpp:480