Indexsets.hpp
Go to the documentation of this file.
1//===========================================================================
2//
3// File: Indexsets.hpp
4//
5// Created: Fri May 29 23:30:01 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/*
17Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18Copyright 2009, 2010, 2022 Equinor ASA.
19
20This file is part of The Open Porous Media project (OPM).
21
22OPM is free software: you can redistribute it and/or modify
23it under the terms of the GNU General Public License as published by
24the Free Software Foundation, either version 3 of the License, or
25(at your option) any later version.
26
27OPM is distributed in the hope that it will be useful,
28but WITHOUT ANY WARRANTY; without even the implied warranty of
29MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30GNU General Public License for more details.
31
32You should have received a copy of the GNU General Public License
33along with OPM. If not, see <http://www.gnu.org/licenses/>.
34*/
35
36#ifndef OPM_INDEXSETS_HEADER
37#define OPM_INDEXSETS_HEADER
38
39#include <dune/geometry/type.hh>
40#include <opm/common/ErrorMacros.hpp>
41#include "GlobalIdMapping.hpp"
42#include "Intersection.hpp"
43
44#include <cstdint>
45#include <unordered_map>
46#include <utility>
47
48namespace Dune
49{
50 namespace cpgrid
51 {
56 {
57 public:
60 typedef std::int64_t IndexType;
61
63 template <int cc>
64 struct Codim
65 {
67 };
68
71 typedef std::vector<GeometryType> Types;
72
76 IndexSet() : IndexSet(0,0){}
77
78 IndexSet(std::size_t numCells, std::size_t numPoints)
79 {
80 geom_types_[0].emplace_back(Dune::GeometryTypes::cube(3));
81 geom_types_[3].emplace_back(Dune::GeometryTypes::cube(0));
82 size_codim_map_[0] = numCells;
83 size_codim_map_[3] = numPoints;
84 }
85
88 {}
89
94 const Types& geomTypes(int codim) const
95 {
96 return geom_types_[codim];
97 }
98
103 const Types& types(int codim) const
104 {
105 return geom_types_[codim];
106 }
107
112 int size(GeometryType type) const
113 {
114 if (type.isCube()) {
115 return size(3 - type.dim()); // return grid_.size(type);
116 } else {
117 return 0;
118 }
119 }
120
121
126 int size(int codim) const
127 {
128 return size_codim_map_[codim]; //grid_.size(codim)
129 }
130
131
137 template<int cd>
139 {
140 return e.index();
141 }
142
148 template<class EntityType>
149 IndexType index(const EntityType& e) const
150 {
151 return e.index();
152 }
153
159 template <int cc>
160 IndexType subIndex(const cpgrid::Entity<0>& e, int i) const
161 {
162 return index(e.template subEntity<cc>(i));
163 }
164
170 IndexType subIndex(const cpgrid::Entity<0>& e, int i, unsigned int cc) const;
171
172
173 template<int codim>
174 IndexType subIndex(const cpgrid::Entity<codim>& /* e */, int /* i */, unsigned int /* cc */) const
175 {
176 DUNE_THROW(NotImplemented, "subIndex not implemented for codim"
177 << codim << "entities.");
178 }
184 template <class EntityType>
185 bool contains(const EntityType& e) const
186 {
187 // return index(e) >= 0 && index(e) < grid_.size(EntityType::codimension); //EntityType::codimension == 0;
188 return index(e) >= 0 && index(e) < this->size(EntityType::codimension);
189 }
190
191 private:
192 // const CpGridData& grid_;
193 Types geom_types_[4];
194 std::array<int,4> size_codim_map_{0,0,0,0};
195 };
196
197
198 class IdSet
199 {
202 //friend class Dune::cpgrid::LevelGlobalIdSet; Not needed due to repeated code in LevelGlobalIdSet (computeId_cell and computeId_point)
203 public:
204 typedef std::int64_t IdType;
205
206 explicit IdSet(const CpGridData& grid)
207 : grid_(grid)
208 {
209 }
210
212 {
213 return computeId_cell(e);
214 }
215
217 {
218 return computeId_point(e);
219 }
220
221 template<class EntityType>
222 IdType id(const EntityType& e) const
223 {
224 return computeId(e);
225 }
226
228 IdType id( const cpgrid::Intersection& intersection ) const
229 {
230 return intersection.id();
231 }
232
233 template<int cc>
234 IdType subId(const cpgrid::Entity<0>& e, int i) const
235 {
236 return id(e.template subEntity<cc>(i));
237 }
238
239 IdType subId(const cpgrid::Entity<0>& e, int i, int cc) const;
240
241 private:
242
243 template<class EntityType>
244 IdType computeId(const EntityType& e) const
245 {
246 IdType myId = 0;
247 for( int c=0; c<EntityType::codimension; ++c )
248 myId += grid_.indexSet().size( c );
249 return myId + e.index();
250 }
251
252 const CpGridData& grid_;
253
254 IdType computeId_cell(const cpgrid::Entity<0>& e) const
255 {
256 IdType myId = 0;
257 // Case: Leaf grid view is a mixed of coarse and fined cells.
258 if (grid_.levelData().size() > 1) {
259 const auto& gridIdx = grid_.getGridIdx();
260 // Level zero grid
261 if ( gridIdx == 0 ) {
262 return myId + e.index();
263 }
264 // Level 1, 2, ...., maxLevel refined grids
265 if ( (gridIdx>0) && (gridIdx < static_cast<int>(grid_.levelData().size() -1)) ) {
266 if ((e.level() != gridIdx)) { // cells equiv to pre-existing cells
267 return grid_.levelData()[e.level()]->localIdSet().id(e.getLevelElem());
268 }
269 else {
270 // Count (and add to myId) all the entities of all the codimensions (for CpGrid, only 0 and 3)
271 // from all the "previous" level grids.
272 for (int lowerLevel = 0; lowerLevel< gridIdx; ++lowerLevel) {
273 for( int c=0; c<4; ++c ) {
274 myId += grid_.levelData()[lowerLevel]->indexSet().size( c );
275 }
276 }
277 return myId + e.index();
278 }
279 }
280 else { // Leaf grid view (grid view with mixed coarse and refined cells).
281 assert( grid_.getGridIdx() == (static_cast<int>(grid_.levelData().size()) -1) );
282 // In this case, we search for the ids defined in previous levels
283 // (since each entities must keep its id along the entire hiearchy)
284 const std::array<int,2> level_levelIdx = grid_.leaf_to_level_cells_[e.index()];
285 const auto& levelEntity = cpgrid::Entity<0>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
286 return grid_.levelData()[level_levelIdx[0]]->local_id_set_ ->id(levelEntity);
287 }
288 } // end-if-data_.size()>1
289 else { // Case: No LGRs / No refined level grids. Only level 0 grid (GLOBAL grid).
290 return myId + e.index();
291 }
292 }
293
294 IdType computeId_point(const cpgrid::Entity<3>& e) const
295 {
296 IdType myId = 0;
297 // Case: Leaf grid view is a mixed of coarse and fined cells.
298 if (grid_.levelData().size() > 1) {
299 const auto& gridIdx = grid_.getGridIdx();
300 // Level zero grid
301 if ( gridIdx == 0 ) {
302 // Count all the entities of (all the levels) level 0 of all codimensions lower than 3 (for CpGrid, only codim = 0 cells).
303 for( int c=0; c<3; ++c ) {
304 myId += grid_.indexSet().size( c );
305 }
306 return myId + e.index();
307 }
308 // Level 1, 2, ...., maxLevel refined grids.
309 if ( (gridIdx>0) && (gridIdx < static_cast<int>(grid_.levelData().size() -1)) ) {
310 const auto& level_levelIdx = grid_.corner_history_[e.index()];
311 if(level_levelIdx[0] != -1) { // corner equiv to a pre-exisiting level corner
312 const auto& levelEntity = cpgrid::Entity<3>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
313 return grid_.levelData()[level_levelIdx[0]]->localIdSet().id(levelEntity);
314 }
315 else {
316 // Count (and add to myId) all the entities of all the codimensions (for CpGrid, only 0 and 3)
317 // from all the "previous" level grids.
318 for (int lowerLevel = 0; lowerLevel< gridIdx; ++lowerLevel) {
319 for( int c=0; c<4; ++c ) {
320 myId += grid_.levelData()[lowerLevel]->indexSet().size( c );
321 }
322 }
323 // Count (and add to myId) all the entities of the refined level grid of codim < 3.
324 for( int c=0; c<3; ++c ) {
325 myId += grid_.indexSet().size( c );
326 }
327 return myId + e.index();
328 }
329 }
330 else { // Leaf grid view (grid view with mixed coarse and refined cells).
331 assert( grid_.getGridIdx() == (static_cast<int>(grid_.levelData().size()) -1) );
332 // In this case, we search for the ids defined in previous levels
333 // (since each entities must keep its id along the entire hiearchy)
334 const std::array<int,2> level_levelIdx = grid_.corner_history_[e.index()];
335 const auto& levelEntity = cpgrid::Entity<3>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
336 return grid_.levelData()[level_levelIdx[0]]->local_id_set_ ->id(levelEntity);
337 }
338 } // end-if-data_.size()>1
339 else { // Case: No LGRs / No refined level grids. Only level 0 grid (GLOBAL grid).
340 for( int c=0; c<3; ++c ) {
341 myId += grid_.indexSet().size( c );
342 }
343 return myId + e.index();
344 }
345 }
346 };
347
348
350 {
351 friend class CpGridData;
353 public:
354 typedef std::int64_t IdType;
355
356 void swap(std::vector<int>& cellMapping,
357 std::vector<int>& faceMapping,
358 std::vector<int>& pointMapping)
359 {
360 idSet_=nullptr;
361 GlobalIdMapping::swap(cellMapping,
362 faceMapping,
363 pointMapping);
364 }
365 LevelGlobalIdSet(std::shared_ptr<const IdSet> ids, const CpGridData* view)
366 : idSet_(std::move(ids)), view_(view)
367 {}
369 : idSet_(), view_()
370 {}
371 template<int codim>
372 IdType id(const Entity<codim>& e) const
373 {
374 assert(view_ == e.pgrid_);
375 // We need to ask the local id set with the full entity
376 // as it needs to be able to determine the level and other
377 // things that are not available in EntityRep.
378 if(idSet_)
379 return idSet_->id(e);
380 else
381 // This a parallel grid and we need to use the mapping
382 // build from the ids of the sequential grid
383 return this->template getMapping<codim>()[e.index()];
384 }
385 template<int codim>
386 IdType id(const EntityRep<codim>& e) const
387 {
388 if(idSet_)
389 return idSet_->id(e);
390 else
391 return this->template getMapping<codim>()[e.index()];
392 }
393
394 template<int cc>
395 IdType subId(const cpgrid::Entity<0>& e, int i) const
396 {
397 assert(view_ == e.pgrid_);
398 return id(e.template subEntity<cc>(i));
399 }
400
401 IdType subId(const cpgrid::Entity<0>& e, int i, int cc) const;
402
403 template<int codim>
405 {
406 if(idSet_)
407 {
408 IdType max_codim_id = 0;
409 if (codim == 0) {
410 for (int elemIdx = 0; elemIdx < view_-> size(0); ++elemIdx) {
411 const auto& element= cpgrid::Entity<0>(*view_, elemIdx, true);
412 max_codim_id = std::max(max_codim_id, idSet_->id(element));
413 }
414 }
415 if (codim == 3) {
416 for (int pointIdx = 0; pointIdx < view_->size(3); ++pointIdx) {
417 const auto& point = cpgrid::Entity<3>(*view_, pointIdx, true);
418 max_codim_id = std::max(max_codim_id, idSet_->id(point));
419 }
420 }
421 return max_codim_id;
422 }
423 else {
424 // This a parallel grid and we need to use the mapping
425 // build from the ids of the sequential grid
426 auto max_elem_codim = std::max_element(this->template getMapping<codim>().begin(),
427 this->template getMapping<codim>().end());
428 return *max_elem_codim;
429 }
430 }
431
433 {
434 // Ignore faces
435 return std::max(getMaxCodimGlobalId<0>(), getMaxCodimGlobalId<3>());
436 }
437
438 private:
439 std::shared_ptr<const IdSet> idSet_;
440 const CpGridData* view_;
441 };
442
450 {
451 public:
454
455 explicit GlobalIdSet(const CpGridData& view);
456
457 template<int codim>
458 IdType id(const Entity<codim>& e) const
459 {
460 return levelIdSet(e.pgrid_).id(e);
461 }
462
463 template<int cc>
464 IdType subId(const cpgrid::Entity<0>& e, int i) const
465 {
466 return levelIdSet(e.pgrid_).template subId<cc>(e, i);
467 }
468
469 IdType subId(const cpgrid::Entity<0>& e, int i, int cc) const;
470
471 void insertIdSet(const CpGridData& view);
472 private:
474 const LevelGlobalIdSet& levelIdSet(const CpGridData* const data) const
475 {
476 auto candidate = idSets_.find(data);
477 assert(candidate != idSets_.end());
478 return *candidate->second;
479 }
481 std::map<const CpGridData* const, std::shared_ptr<const LevelGlobalIdSet>> idSets_;
482 };
483
485 {
486 public:
488 {
489 if(idSet.idSet_)
490 {
491 grid_ = &(idSet.idSet_->grid_);
492 }
493 else
494 {
495 mapping_.reset(new std::unordered_map<int,int>);
496 int localId = 0;
497 for (const auto& globalId: idSet.template getMapping<3>())
498 (*mapping_)[globalId] = localId++;
499 }
500 }
501 int operator[](int i) const
502 {
503 if (mapping_)
504 {
505 return(*mapping_)[i];
506 }
507 else if (grid_)
508 {
509 return i - grid_->size(0) - grid_->size(1) - grid_->size(2);
510 }
511
512 OPM_THROW(std::runtime_error, "No grid or mapping. Should not be here!");
513 }
514 void release()
515 {
516 mapping_.reset(nullptr);
517 }
518 private:
519 std::unique_ptr<std::unordered_map<int,int> > mapping_;
520 const CpGridData* grid_ = nullptr;
521 };
522
523 } // namespace cpgrid
524} // namespace Dune
525
526#endif // OPM_INDEXSETS_HEADER
DataHandle & data
Definition: CpGridData.hpp:1250
Struct that hods all the data needed to represent a Cpgrid.
Definition: CpGridData.hpp:138
int size(int codim) const
number of leaf entities per codim in this process
const IndexSet & indexSet() const
Definition: CpGridData.hpp:654
const std::vector< std::shared_ptr< Dune::cpgrid::CpGridData > > & levelData() const
Add doc/or remove method and replace it with better approach.
Definition: CpGridData.hpp:535
int getGridIdx() const
Add doc/or remove method and replace it with better approach.
Definition: CpGridData.hpp:521
Definition: Entity.hpp:71
const CpGridData * pgrid_
Definition: Entity.hpp:297
Entity< 0 > getLevelElem() const
Get equivalent element on the level grid where the entity was born, if grid = leaf-grid-view....
Definition: Entity.hpp:581
int level() const
Return the level of the entity in the grid hierarchy. Level = 0 represents the coarsest grid.
Definition: Entity.hpp:433
Represents an entity of a given codim, with positive or negative orientation.
Definition: EntityRep.hpp:99
int index() const
The (positive) index of an entity. Not a Dune interface method.
Definition: EntityRep.hpp:126
Class managing the mappings of local indices to global ids.
Definition: GlobalIdMapping.hpp:31
void swap(std::vector< int > &cellMapping, std::vector< int > &faceMapping, std::vector< int > &pointMapping)
Swap data for initialization.
Definition: GlobalIdMapping.hpp:38
The global id set for Dune.
Definition: Indexsets.hpp:450
typename LevelGlobalIdSet::IdType IdType
The type of the id.
Definition: Indexsets.hpp:453
void insertIdSet(const CpGridData &view)
GlobalIdSet(const CpGridData &view)
IdType subId(const cpgrid::Entity< 0 > &e, int i, int cc) const
IdType id(const Entity< codim > &e) const
Definition: Indexsets.hpp:458
IdType subId(const cpgrid::Entity< 0 > &e, int i) const
Definition: Indexsets.hpp:464
Definition: Indexsets.hpp:199
IdType subId(const cpgrid::Entity< 0 > &e, int i) const
Definition: Indexsets.hpp:234
IdType id(const EntityType &e) const
Definition: Indexsets.hpp:222
IdSet(const CpGridData &grid)
Definition: Indexsets.hpp:206
IdType id(const cpgrid::Entity< 3 > &e) const
Definition: Indexsets.hpp:216
IdType id(const cpgrid::Intersection &intersection) const
return id of intersection (here face number)
Definition: Indexsets.hpp:228
IdType subId(const cpgrid::Entity< 0 > &e, int i, int cc) const
std::int64_t IdType
Definition: Indexsets.hpp:204
IdType id(const cpgrid::Entity< 0 > &e) const
Definition: Indexsets.hpp:211
Definition: Indexsets.hpp:56
bool contains(const EntityType &e) const
Definition: Indexsets.hpp:185
IndexSet(std::size_t numCells, std::size_t numPoints)
Definition: Indexsets.hpp:78
int size(int codim) const
Definition: Indexsets.hpp:126
IndexType subIndex(const cpgrid::Entity< 0 > &e, int i) const
Definition: Indexsets.hpp:160
const Types & types(int codim) const
Definition: Indexsets.hpp:103
~IndexSet()
Destructor.
Definition: Indexsets.hpp:87
std::vector< GeometryType > Types
Definition: Indexsets.hpp:71
IndexType subIndex(const cpgrid::Entity< 0 > &e, int i, unsigned int cc) const
std::int64_t IndexType
Definition: Indexsets.hpp:60
IndexType index(const EntityType &e) const
Definition: Indexsets.hpp:149
IndexType index(const cpgrid::Entity< cd > &e) const
Definition: Indexsets.hpp:138
int size(GeometryType type) const
Definition: Indexsets.hpp:112
IndexSet()
Definition: Indexsets.hpp:76
const Types & geomTypes(int codim) const
Definition: Indexsets.hpp:94
IndexType subIndex(const cpgrid::Entity< codim > &, int, unsigned int) const
Definition: Indexsets.hpp:174
Definition: Intersection.hpp:66
int id() const
Definition: Intersection.hpp:234
Definition: Indexsets.hpp:350
void swap(std::vector< int > &cellMapping, std::vector< int > &faceMapping, std::vector< int > &pointMapping)
Definition: Indexsets.hpp:356
LevelGlobalIdSet()
Definition: Indexsets.hpp:368
IdType subId(const cpgrid::Entity< 0 > &e, int i, int cc) const
IdType id(const Entity< codim > &e) const
Definition: Indexsets.hpp:372
IdType subId(const cpgrid::Entity< 0 > &e, int i) const
Definition: Indexsets.hpp:395
std::int64_t IdType
Definition: Indexsets.hpp:354
IdType getMaxGlobalId()
Definition: Indexsets.hpp:432
IdType getMaxCodimGlobalId()
Definition: Indexsets.hpp:404
IdType id(const EntityRep< codim > &e) const
Definition: Indexsets.hpp:386
LevelGlobalIdSet(std::shared_ptr< const IdSet > ids, const CpGridData *view)
Definition: Indexsets.hpp:365
Definition: Indexsets.hpp:485
ReversePointGlobalIdSet(const LevelGlobalIdSet &idSet)
Definition: Indexsets.hpp:487
int operator[](int i) const
Definition: Indexsets.hpp:501
void release()
Definition: Indexsets.hpp:514
The namespace Dune is the main namespace for all Dune code.
Definition: common/CartesianIndexMapper.hpp:10
int numCells(const Dune::CpGrid &grid)
Get the number of cells of a grid.
STL namespace.
Export the type of the entity used as parameter in the index(...) method.
Definition: Indexsets.hpp:65
cpgrid::Entity< cc > Entity
Definition: Indexsets.hpp:66