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
62 static constexpr int dimension = 3;
63
65 template <int cc>
66 struct Codim
67 {
69 };
70
73 typedef std::vector<GeometryType> Types;
74
78 IndexSet() : IndexSet(0,0){}
79
80 IndexSet(std::size_t numCells, std::size_t numPoints)
81 {
82 geom_types_[0].emplace_back(Dune::GeometryTypes::cube(3));
83 geom_types_[3].emplace_back(Dune::GeometryTypes::cube(0));
84 size_codim_map_[0] = numCells;
85 size_codim_map_[3] = numPoints;
86 }
87
90 {}
91
96 const Types& geomTypes(int codim) const
97 {
98 return geom_types_[codim];
99 }
100
105 const Types& types(int codim) const
106 {
107 return geom_types_[codim];
108 }
109
114 int size(GeometryType type) const
115 {
116 if (type.isCube()) {
117 return size(3 - type.dim()); // return grid_.size(type);
118 } else {
119 return 0;
120 }
121 }
122
123
128 int size(int codim) const
129 {
130 return size_codim_map_[codim]; //grid_.size(codim)
131 }
132
133
139 template<int cd>
141 {
142 return e.index();
143 }
144
150 template<class EntityType>
151 IndexType index(const EntityType& e) const
152 {
153 return e.index();
154 }
155
161 template <int cc>
162 IndexType subIndex(const cpgrid::Entity<0>& e, int i) const
163 {
164 return index(e.template subEntity<cc>(i));
165 }
166
172 IndexType subIndex(const cpgrid::Entity<0>& e, int i, unsigned int cc) const;
173
174
175 template<int codim>
176 IndexType subIndex(const cpgrid::Entity<codim>& /* e */, int /* i */, unsigned int /* cc */) const
177 {
178 DUNE_THROW(NotImplemented, "subIndex not implemented for codim"
179 << codim << "entities.");
180 }
186 template <class EntityType>
187 bool contains(const EntityType& e) const
188 {
189 // return index(e) >= 0 && index(e) < grid_.size(EntityType::codimension); //EntityType::codimension == 0;
190 return index(e) >= 0 && index(e) < this->size(EntityType::codimension);
191 }
192
193 private:
194 // const CpGridData& grid_;
195 Types geom_types_[4];
196 std::array<int,4> size_codim_map_{0,0,0,0};
197 };
198
199
200 class IdSet
201 {
204 //friend class Dune::cpgrid::LevelGlobalIdSet; Not needed due to repeated code in LevelGlobalIdSet (computeId_cell and computeId_point)
205 public:
206 typedef std::int64_t IdType;
207
208 static constexpr int dimension = 3;
209
211 template <int cc>
212 struct Codim
213 {
215 };
216
217 explicit IdSet(const CpGridData& grid)
218 : grid_(grid)
219 {
220 }
221
222 template <int cd>
223 IdType id(const typename Codim<cd>::Entity& e) const
224 {
225 if constexpr (cd == 0)
226 return computeId_cell(e);
227 else if constexpr (cd == 1)
228 return computeId(e);
229 else if constexpr (cd == 3)
230 return computeId_point(e);
231 else
232 static_assert(AlwaysFalse<index_constant<cd>>::value,
233 "IdSet::id not implemented for codims other thatn 0, 1, and 3.");
234 }
235
236 template<class EntityType>
237 IdType id(const EntityType& e) const
238 {
239 return id<EntityType::codimension>(e);
240 }
241
242 template<int codim>
244 {
245 return computeId(e);
246 }
247
249 IdType id( const cpgrid::Intersection& intersection ) const
250 {
251 return intersection.id();
252 }
253
254 template<int cc>
255 IdType subId(const cpgrid::Entity<0>& e, int i) const
256 {
257 return id(e.template subEntity<cc>(i));
258 }
259
260 IdType subId(const cpgrid::Entity<0>& e, int i, int cc) const;
261
262 private:
263
264 template<class EntityType>
265 IdType computeId(const EntityType& e) const
266 {
267 IdType myId = 0;
268 for( int c=0; c<EntityType::codimension; ++c )
269 myId += grid_.indexSet().size( c );
270 return myId + e.index();
271 }
272
273 const CpGridData& grid_;
274
275 IdType computeId_cell(const cpgrid::Entity<0>& e) const
276 {
277 IdType myId = 0;
278 // Case: Leaf grid view is a mixed of coarse and fined cells.
279 if (grid_.levelData().size() > 1) {
280 const auto& gridIdx = grid_.getGridIdx();
281 // Level zero grid
282 if ( gridIdx == 0 ) {
283 return myId + e.index();
284 }
285 // Level 1, 2, ...., maxLevel refined grids
286 if ( (gridIdx>0) && (gridIdx < static_cast<int>(grid_.levelData().size() -1)) ) {
287 if ((e.level() != gridIdx)) { // cells equiv to pre-existing cells
288 return grid_.levelData()[e.level()]->localIdSet().id(e.getLevelElem());
289 }
290 else {
291 // Count (and add to myId) all the entities of all the codimensions (for CpGrid, only 0 and 3)
292 // from all the "previous" level grids.
293 for (int lowerLevel = 0; lowerLevel< gridIdx; ++lowerLevel) {
294 for( int c=0; c<4; ++c ) {
295 myId += grid_.levelData()[lowerLevel]->indexSet().size( c );
296 }
297 }
298 return myId + e.index();
299 }
300 }
301 else { // Leaf grid view (grid view with mixed coarse and refined cells).
302 assert( grid_.getGridIdx() == (static_cast<int>(grid_.levelData().size()) -1) );
303 // In this case, we search for the ids defined in previous levels
304 // (since each entities must keep its id along the entire hiearchy)
305 const std::array<int,2> level_levelIdx = grid_.leaf_to_level_cells_[e.index()];
306 const auto& levelEntity = cpgrid::Entity<0>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
307 return grid_.levelData()[level_levelIdx[0]]->local_id_set_ ->id(levelEntity);
308 }
309 } // end-if-data_.size()>1
310 else { // Case: No LGRs / No refined level grids. Only level 0 grid (GLOBAL grid).
311 return myId + e.index();
312 }
313 }
314
315 IdType computeId_point(const cpgrid::Entity<3>& e) const
316 {
317 IdType myId = 0;
318 // Case: Leaf grid view is a mixed of coarse and fined cells.
319 if (grid_.levelData().size() > 1) {
320 const auto& gridIdx = grid_.getGridIdx();
321 // Level zero grid
322 if ( gridIdx == 0 ) {
323 // Count all the entities of (all the levels) level 0 of all codimensions lower than 3 (for CpGrid, only codim = 0 cells).
324 for( int c=0; c<3; ++c ) {
325 myId += grid_.indexSet().size( c );
326 }
327 return myId + e.index();
328 }
329 // Level 1, 2, ...., maxLevel refined grids.
330 if ( (gridIdx>0) && (gridIdx < static_cast<int>(grid_.levelData().size() -1)) ) {
331 const auto& level_levelIdx = grid_.corner_history_[e.index()];
332 if(level_levelIdx[0] != -1) { // corner equiv to a pre-exisiting level corner
333 const auto& levelEntity = cpgrid::Entity<3>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
334 return grid_.levelData()[level_levelIdx[0]]->localIdSet().id(levelEntity);
335 }
336 else {
337 // Count (and add to myId) all the entities of all the codimensions (for CpGrid, only 0 and 3)
338 // from all the "previous" level grids.
339 for (int lowerLevel = 0; lowerLevel< gridIdx; ++lowerLevel) {
340 for( int c=0; c<4; ++c ) {
341 myId += grid_.levelData()[lowerLevel]->indexSet().size( c );
342 }
343 }
344 // Count (and add to myId) all the entities of the refined level grid of codim < 3.
345 for( int c=0; c<3; ++c ) {
346 myId += grid_.indexSet().size( c );
347 }
348 return myId + e.index();
349 }
350 }
351 else { // Leaf grid view (grid view with mixed coarse and refined cells).
352 assert( grid_.getGridIdx() == (static_cast<int>(grid_.levelData().size()) -1) );
353 // In this case, we search for the ids defined in previous levels
354 // (since each entities must keep its id along the entire hiearchy)
355 const std::array<int,2> level_levelIdx = grid_.corner_history_[e.index()];
356 const auto& levelEntity = cpgrid::Entity<3>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
357 return grid_.levelData()[level_levelIdx[0]]->local_id_set_ ->id(levelEntity);
358 }
359 } // end-if-data_.size()>1
360 else { // Case: No LGRs / No refined level grids. Only level 0 grid (GLOBAL grid).
361 for( int c=0; c<3; ++c ) {
362 myId += grid_.indexSet().size( c );
363 }
364 return myId + e.index();
365 }
366 }
367 };
368
369
371 {
372 friend class CpGridData;
374 public:
375 typedef std::int64_t IdType;
376
377 static constexpr int dimension = 3;
378
380 template <int cc>
381 struct Codim
382 {
384 };
385
386 void swap(std::vector<int>& cellMapping,
387 std::vector<int>& faceMapping,
388 std::vector<int>& pointMapping)
389 {
390 idSet_=nullptr;
391 GlobalIdMapping::swap(cellMapping,
392 faceMapping,
393 pointMapping);
394 }
395 LevelGlobalIdSet(std::shared_ptr<const IdSet> ids, const CpGridData* view)
396 : idSet_(std::move(ids)), view_(view)
397 {}
399 : idSet_(), view_()
400 {}
401 template<int codim>
402 IdType id(const typename Codim<codim>::Entity& e) const
403 {
404 assert(view_ == e.pgrid_);
405 // We need to ask the local id set with the full entity
406 // as it needs to be able to determine the level and other
407 // things that are not available in EntityRep.
408 if(idSet_)
409 return idSet_->id(e);
410 else
411 // This a parallel grid and we need to use the mapping
412 // build from the ids of the sequential grid
413 return this->template getMapping<codim>()[e.index()];
414 }
415
416 template<int codim>
417 IdType id(const EntityRep<codim>& e) const
418 {
419 if(idSet_)
420 return idSet_->id(e);
421 else
422 return this->template getMapping<codim>()[e.index()];
423 }
424
425 template<class EntityType>
426 IdType id(const EntityType& e) const
427 {
428 return id<EntityType::codimension>(e);
429 }
430
431 template<int cc>
432 IdType subId(const cpgrid::Entity<0>& e, int i) const
433 {
434 assert(view_ == e.pgrid_);
435 return id(e.template subEntity<cc>(i));
436 }
437
438 IdType subId(const cpgrid::Entity<0>& e, int i, int cc) const;
439
440 template<int codim>
442 {
443 if(idSet_)
444 {
445 IdType max_codim_id = 0;
446 if (codim == 0) {
447 for (int elemIdx = 0; elemIdx < view_-> size(0); ++elemIdx) {
448 const auto& element= cpgrid::Entity<0>(*view_, elemIdx, true);
449 max_codim_id = std::max(max_codim_id, idSet_->id(element));
450 }
451 }
452 if (codim == 3) {
453 for (int pointIdx = 0; pointIdx < view_->size(3); ++pointIdx) {
454 const auto& point = cpgrid::Entity<3>(*view_, pointIdx, true);
455 max_codim_id = std::max(max_codim_id, idSet_->id(point));
456 }
457 }
458 return max_codim_id;
459 }
460 else {
461 // This a parallel grid and we need to use the mapping
462 // build from the ids of the sequential grid
463 auto max_elem_codim = std::max_element(this->template getMapping<codim>().begin(),
464 this->template getMapping<codim>().end());
465 return *max_elem_codim;
466 }
467 }
468
470 {
471 // Ignore faces
472 return std::max(getMaxCodimGlobalId<0>(), getMaxCodimGlobalId<3>());
473 }
474
475 private:
476 std::shared_ptr<const IdSet> idSet_;
477 const CpGridData* view_;
478 };
479
487 {
488 public:
491
492 static constexpr int dimension = 3;
493
495 template <int cd>
496 struct Codim
497 {
499 };
500
501 explicit GlobalIdSet(const CpGridData& view);
502
503 template<int codim>
504 IdType id(const typename Codim<codim>::Entity& e) const
505 {
506 return levelIdSet(e.pgrid_).id(e);
507 }
508
509 template<class EntityType>
510 IdType id(const EntityType& e) const
511 {
512 return id<EntityType::codimension>(e);
513 }
514
515 template <int cc>
516 IdType subId(const typename Codim<0>::Entity& e, int i) const
517 {
518 return levelIdSet(e.pgrid_).template subId<cc>(e, i);
519 }
520
521 IdType subId(const typename Codim<0>::Entity& e, int i, int cc) const;
522
523 void insertIdSet(const CpGridData& view);
524 private:
526 const LevelGlobalIdSet& levelIdSet(const CpGridData* const data) const
527 {
528 auto candidate = idSets_.find(data);
529 assert(candidate != idSets_.end());
530 return *candidate->second;
531 }
533 std::map<const CpGridData* const, std::shared_ptr<const LevelGlobalIdSet>> idSets_;
534 };
535
537 {
538 public:
540 {
541 if(idSet.idSet_)
542 {
543 grid_ = &(idSet.idSet_->grid_);
544 }
545 else
546 {
547 mapping_.reset(new std::unordered_map<int,int>);
548 int localId = 0;
549 for (const auto& globalId: idSet.template getMapping<3>())
550 (*mapping_)[globalId] = localId++;
551 }
552 }
553 int operator[](int i) const
554 {
555 if (mapping_)
556 {
557 return(*mapping_)[i];
558 }
559 else if (grid_)
560 {
561 return i - grid_->size(0) - grid_->size(1) - grid_->size(2);
562 }
563
564 OPM_THROW(std::runtime_error, "No grid or mapping. Should not be here!");
565 }
566 void release()
567 {
568 mapping_.reset(nullptr);
569 }
570 private:
571 std::unique_ptr<std::unordered_map<int,int> > mapping_;
572 const CpGridData* grid_ = nullptr;
573 };
574
575 } // namespace cpgrid
576} // namespace Dune
577
578#endif // OPM_INDEXSETS_HEADER
DataHandle & data
Definition: CpGridData.hpp:1183
Struct that hods all the data needed to represent a Cpgrid.
Definition: CpGridData.hpp:118
int size(int codim) const
number of leaf entities per codim in this process
const IndexSet & indexSet() const
Definition: CpGridData.hpp:586
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:474
int getGridIdx() const
Add doc/or remove method and replace it with better approach.
Definition: CpGridData.hpp:460
Definition: Entity.hpp:72
const CpGridData * pgrid_
Definition: Entity.hpp:298
Entity< 0 > getLevelElem() const
Get equivalent element on the level grid where the entity was born, if grid = leaf-grid-view....
Definition: Entity.hpp:598
int level() const
Return the level of the entity in the grid hierarchy. Level = 0 represents the coarsest grid.
Definition: Entity.hpp:442
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:487
typename LevelGlobalIdSet::IdType IdType
The type of the id.
Definition: Indexsets.hpp:490
void insertIdSet(const CpGridData &view)
GlobalIdSet(const CpGridData &view)
IdType id(const typename Codim< codim >::Entity &e) const
Definition: Indexsets.hpp:504
IdType subId(const typename Codim< 0 >::Entity &e, int i) const
Definition: Indexsets.hpp:516
IdType id(const EntityType &e) const
Definition: Indexsets.hpp:510
IdType subId(const typename Codim< 0 >::Entity &e, int i, int cc) const
Definition: Indexsets.hpp:201
IdType subId(const cpgrid::Entity< 0 > &e, int i) const
Definition: Indexsets.hpp:255
IdType id(const EntityType &e) const
Definition: Indexsets.hpp:237
IdSet(const CpGridData &grid)
Definition: Indexsets.hpp:217
static constexpr int dimension
Definition: Indexsets.hpp:208
IdType id(const cpgrid::Intersection &intersection) const
return id of intersection (here face number)
Definition: Indexsets.hpp:249
IdType id(const cpgrid::EntityRep< codim > &e) const
Definition: Indexsets.hpp:243
IdType id(const typename Codim< cd >::Entity &e) const
Definition: Indexsets.hpp:223
IdType subId(const cpgrid::Entity< 0 > &e, int i, int cc) const
std::int64_t IdType
Definition: Indexsets.hpp:206
Definition: Indexsets.hpp:56
bool contains(const EntityType &e) const
Definition: Indexsets.hpp:187
IndexSet(std::size_t numCells, std::size_t numPoints)
Definition: Indexsets.hpp:80
int size(int codim) const
Definition: Indexsets.hpp:128
IndexType subIndex(const cpgrid::Entity< 0 > &e, int i) const
Definition: Indexsets.hpp:162
static constexpr int dimension
Definition: Indexsets.hpp:62
const Types & types(int codim) const
Definition: Indexsets.hpp:105
~IndexSet()
Destructor.
Definition: Indexsets.hpp:89
std::vector< GeometryType > Types
Definition: Indexsets.hpp:73
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:151
IndexType index(const cpgrid::Entity< cd > &e) const
Definition: Indexsets.hpp:140
int size(GeometryType type) const
Definition: Indexsets.hpp:114
IndexSet()
Definition: Indexsets.hpp:78
const Types & geomTypes(int codim) const
Definition: Indexsets.hpp:96
IndexType subIndex(const cpgrid::Entity< codim > &, int, unsigned int) const
Definition: Indexsets.hpp:176
Definition: Intersection.hpp:66
int id() const
Definition: Intersection.hpp:235
Definition: Indexsets.hpp:371
void swap(std::vector< int > &cellMapping, std::vector< int > &faceMapping, std::vector< int > &pointMapping)
Definition: Indexsets.hpp:386
LevelGlobalIdSet()
Definition: Indexsets.hpp:398
IdType subId(const cpgrid::Entity< 0 > &e, int i, int cc) const
IdType subId(const cpgrid::Entity< 0 > &e, int i) const
Definition: Indexsets.hpp:432
IdType getMaxGlobalId() const
Definition: Indexsets.hpp:469
std::int64_t IdType
Definition: Indexsets.hpp:375
static constexpr int dimension
Definition: Indexsets.hpp:377
IdType id(const EntityType &e) const
Definition: Indexsets.hpp:426
IdType id(const EntityRep< codim > &e) const
Definition: Indexsets.hpp:417
IdType id(const typename Codim< codim >::Entity &e) const
Definition: Indexsets.hpp:402
IdType getMaxCodimGlobalId() const
Definition: Indexsets.hpp:441
LevelGlobalIdSet(std::shared_ptr< const IdSet > ids, const CpGridData *view)
Definition: Indexsets.hpp:395
Definition: Indexsets.hpp:537
ReversePointGlobalIdSet(const LevelGlobalIdSet &idSet)
Definition: Indexsets.hpp:539
int operator[](int i) const
Definition: Indexsets.hpp:553
void release()
Definition: Indexsets.hpp:566
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 supported entity types.
Definition: Indexsets.hpp:497
Export supported entity types.
Definition: Indexsets.hpp:213
Export supported entity types.
Definition: Indexsets.hpp:67
cpgrid::Entity< cc > Entity
Definition: Indexsets.hpp:68
Export supported entity types.
Definition: Indexsets.hpp:382