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 "Entity.hpp"
42#include "GlobalIdMapping.hpp"
43#include "Intersection.hpp"
44
45#include <cstdint>
46#include <unordered_map>
47#include <utility>
48
49namespace Dune
50{
51 namespace cpgrid
52 {
57 {
58 public:
61 typedef std::int64_t IndexType;
62
63 static constexpr int dimension = 3;
64
66 template <int cd>
67 using Codim = typename Impl::CodimTraits<cd>;
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 static constexpr int dimension = 3;
207
209 template <int cd>
210 using Codim = typename Impl::CodimTraits<cd>;
211
212 explicit IdSet(const CpGridData& grid)
213 : grid_(grid)
214 {
215 }
216
217 template <int cd>
218 IdType id(const typename Codim<cd>::Entity& e) const
219 {
220 if constexpr (cd == 0)
221 return computeId_cell(e);
222 else if constexpr (cd == 3)
223 return computeId_point(e);
224 else
225 static_assert(AlwaysFalse<index_constant<cd>>::value,
226 "IdSet::id not implemented for codims other than 0, and 3.");
227 }
228
229 template<class EntityType>
230 IdType id(const EntityType& e) const
231 {
232 return id<EntityType::codimension>(e);
233 }
234
235 template<int codim>
237 {
238 return computeId(e);
239 }
240
241 template<int codim>
242 IdType idLevelZero(const Entity<codim>& e) const = delete;
243
245 IdType id( const cpgrid::Intersection& intersection ) const
246 {
247 return intersection.id();
248 }
249
250 template<int cc>
251 IdType subId(const cpgrid::Entity<0>& e, int i) const
252 {
253 return id(e.template subEntity<cc>(i));
254 }
255
256 IdType subId(const cpgrid::Entity<0>& e, int i, int cc) const;
257
258 private:
259
260 template<class EntityType>
261 IdType computeId(const EntityType& e) const
262 {
263 IdType myId = 0;
264 for( int c=0; c<EntityType::codimension; ++c )
265 myId += grid_.indexSet().size( c );
266 return myId + e.index();
267 }
268
269 const CpGridData& grid_;
270
271 IdType computeId_cell(const cpgrid::Entity<0>& e) const
272 {
273 IdType myId = 0;
274 // Case: Leaf grid view is a mixed of coarse and fined cells.
275 if (grid_.levelData().size() > 1) {
276 const auto& gridIdx = grid_.getGridIdx();
277 // Level zero grid
278 if ( gridIdx == 0 ) {
279 return myId + e.index();
280 }
281 // Level 1, 2, ...., maxLevel refined grids
282 if ( (gridIdx>0) && (gridIdx < static_cast<int>(grid_.levelData().size() -1)) ) {
283 if ((e.level() != gridIdx)) { // cells equiv to pre-existing cells
284 return grid_.levelData()[e.level()]->localIdSet().id(e.getLevelElem());
285 }
286 else {
287 // Count (and add to myId) all the entities of all the codimensions (for CpGrid, only 0 and 3)
288 // from all the "previous" level grids.
289 for (int lowerLevel = 0; lowerLevel< gridIdx; ++lowerLevel) {
290 for( int c=0; c<4; ++c ) {
291 myId += grid_.levelData()[lowerLevel]->indexSet().size( c );
292 }
293 }
294 return myId + e.index();
295 }
296 }
297 else { // Leaf grid view (grid view with mixed coarse and refined cells).
298 assert( grid_.getGridIdx() == (static_cast<int>(grid_.levelData().size()) -1) );
299 // In this case, we search for the ids defined in previous levels
300 // (since each entities must keep its id along the entire hiearchy)
301 const std::array<int,2> level_levelIdx = grid_.leaf_to_level_cells_[e.index()];
302 const auto& levelEntity = cpgrid::Entity<0>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
303 return grid_.levelData()[level_levelIdx[0]]->local_id_set_ ->id(levelEntity);
304 }
305 } // end-if-data_.size()>1
306 else { // Case: No LGRs / No refined level grids. Only level 0 grid (GLOBAL grid).
307 return myId + e.index();
308 }
309 }
310
311 IdType computeId_point(const cpgrid::Entity<3>& e) const
312 {
313 IdType myId = 0;
314 // Case: Leaf grid view is a mixed of coarse and fined cells.
315 if (grid_.levelData().size() > 1) {
316 const auto& gridIdx = grid_.getGridIdx();
317 // Level zero grid
318 if ( gridIdx == 0 ) {
319 // Count all the entities of (all the levels) level 0 of all codimensions lower than 3 (for CpGrid, only codim = 0 cells).
320 for( int c=0; c<3; ++c ) {
321 myId += grid_.indexSet().size( c );
322 }
323 return myId + e.index();
324 }
325 // Level 1, 2, ...., maxLevel refined grids.
326 if ( (gridIdx>0) && (gridIdx < static_cast<int>(grid_.levelData().size() -1)) ) {
327 const auto& level_levelIdx = grid_.corner_history_[e.index()];
328 if(level_levelIdx[0] != -1) { // corner equiv to a pre-exisiting level corner
329 const auto& levelEntity = cpgrid::Entity<3>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
330 return grid_.levelData()[level_levelIdx[0]]->localIdSet().id(levelEntity);
331 }
332 else {
333 // Count (and add to myId) all the entities of all the codimensions (for CpGrid, only 0 and 3)
334 // from all the "previous" level grids.
335 for (int lowerLevel = 0; lowerLevel< gridIdx; ++lowerLevel) {
336 for( int c=0; c<4; ++c ) {
337 myId += grid_.levelData()[lowerLevel]->indexSet().size( c );
338 }
339 }
340 // Count (and add to myId) all the entities of the refined level grid of codim < 3.
341 for( int c=0; c<3; ++c ) {
342 myId += grid_.indexSet().size( c );
343 }
344 return myId + e.index();
345 }
346 }
347 else { // Leaf grid view (grid view with mixed coarse and refined cells).
348 assert( grid_.getGridIdx() == (static_cast<int>(grid_.levelData().size()) -1) );
349 // In this case, we search for the ids defined in previous levels
350 // (since each entities must keep its id along the entire hiearchy)
351 const std::array<int,2> level_levelIdx = grid_.corner_history_[e.index()];
352 const auto& levelEntity = cpgrid::Entity<3>(*(grid_.levelData()[level_levelIdx[0]]), level_levelIdx[1], true);
353 return grid_.levelData()[level_levelIdx[0]]->local_id_set_ ->id(levelEntity);
354 }
355 } // end-if-data_.size()>1
356 else { // Case: No LGRs / No refined level grids. Only level 0 grid (GLOBAL grid).
357 for( int c=0; c<3; ++c ) {
358 myId += grid_.indexSet().size( c );
359 }
360 return myId + e.index();
361 }
362 }
363 };
364
365
367 {
368 friend class CpGridData;
370 public:
371 typedef std::int64_t IdType;
372
373 static constexpr int dimension = 3;
374
376 template <int cd>
377 using Codim = typename Impl::CodimTraits<cd>;
378
379 void swap(std::vector<int>& cellMapping,
380 std::vector<int>& faceMapping,
381 std::vector<int>& pointMapping)
382 {
383 idSet_=nullptr;
384 GlobalIdMapping::swap(cellMapping,
385 faceMapping,
386 pointMapping);
387 }
388 LevelGlobalIdSet(std::shared_ptr<const IdSet> ids, const CpGridData* view)
389 : idSet_(std::move(ids)), view_(view)
390 {}
392 : idSet_(), view_()
393 {}
394 template<int codim>
395 IdType id(const typename Codim<codim>::Entity& e) const
396 {
397 assert(view_ == e.pgrid_);
398 // We need to ask the local id set with the full entity
399 // as it needs to be able to determine the level and other
400 // things that are not available in EntityRep.
401 if(idSet_)
402 return idSet_->id(e);
403 else
404 // This a parallel grid and we need to use the mapping
405 // build from the ids of the sequential grid
406 return this->template getMapping<codim>()[e.index()];
407 }
408
409 template<int codim>
411 {
412 if(idSet_)
413 return idSet_->idLevelZero(e);
414 else
415 return this->template getMapping<codim>()[e.index()];
416 }
417
418 template<int codim>
419 IdType idLevelZero(const Entity<codim>& e) const = delete;
420
421 template<class EntityType>
422 IdType id(const EntityType& e) const
423 {
424 return id<EntityType::codimension>(e);
425 }
426
427 template<int cc>
428 IdType subId(const cpgrid::Entity<0>& e, int i) const
429 {
430 assert(view_ == e.pgrid_);
431 return id(e.template subEntity<cc>(i));
432 }
433
434 IdType subId(const cpgrid::Entity<0>& e, int i, int cc) const;
435
436 template<int codim>
438 {
439 if(idSet_)
440 {
441 IdType max_codim_id = 0;
442 if (codim == 0) {
443 for (int elemIdx = 0; elemIdx < view_-> size(0); ++elemIdx) {
444 const auto& element= cpgrid::Entity<0>(*view_, elemIdx, true);
445 max_codim_id = std::max(max_codim_id, idSet_->id(element));
446 }
447 }
448 if (codim == 3) {
449 for (int pointIdx = 0; pointIdx < view_->size(3); ++pointIdx) {
450 const auto& point = cpgrid::Entity<3>(*view_, pointIdx, true);
451 max_codim_id = std::max(max_codim_id, idSet_->id(point));
452 }
453 }
454 return max_codim_id;
455 }
456 else {
457 // This a parallel grid and we need to use the mapping
458 // build from the ids of the sequential grid
459 const auto max_elem_codim =
460 std::ranges::max_element(this->template getMapping<codim>());
461 return *max_elem_codim;
462 }
463 }
464
466 {
467 // Ignore faces
468 return std::max(getMaxCodimGlobalId<0>(), getMaxCodimGlobalId<3>());
469 }
470
471 private:
472 std::shared_ptr<const IdSet> idSet_;
473 const CpGridData* view_;
474 };
475
483 {
484 public:
487
488 static constexpr int dimension = 3;
489
491 template <int cd>
492 using Codim = typename Impl::CodimTraits<cd>;
493
494 explicit GlobalIdSet(const CpGridData& view);
495
496 template<int codim>
497 IdType id(const typename Codim<codim>::Entity& e) const
498 {
499 return levelIdSet(e.pgrid_).id(e);
500 }
501
502 template<class EntityType>
503 IdType id(const EntityType& e) const
504 {
505 return id<EntityType::codimension>(e);
506 }
507
508 template <int cc>
509 IdType subId(const typename Codim<0>::Entity& e, int i) const
510 {
511 return levelIdSet(e.pgrid_).template subId<cc>(e, i);
512 }
513
514 IdType subId(const typename Codim<0>::Entity& e, int i, int cc) const;
515
516 void insertIdSet(const CpGridData& view);
517 private:
519 const LevelGlobalIdSet& levelIdSet(const CpGridData* const data) const
520 {
521 auto candidate = idSets_.find(data);
522 assert(candidate != idSets_.end());
523 return *candidate->second;
524 }
526 std::map<const CpGridData* const, std::shared_ptr<const LevelGlobalIdSet>> idSets_;
527 };
528
530 {
531 public:
533 {
534 if(idSet.idSet_)
535 {
536 grid_ = &(idSet.idSet_->grid_);
537 }
538 else
539 {
540 mapping_.reset(new std::unordered_map<int,int>);
541 int localId = 0;
542 for (const auto& globalId: idSet.template getMapping<3>())
543 (*mapping_)[globalId] = localId++;
544 }
545 }
546 int operator[](int i) const
547 {
548 if (mapping_)
549 {
550 return(*mapping_)[i];
551 }
552 else if (grid_)
553 {
554 return i - grid_->size(0) - grid_->size(1) - grid_->size(2);
555 }
556
557 OPM_THROW(std::runtime_error, "No grid or mapping. Should not be here!");
558 }
559 void release()
560 {
561 mapping_.reset(nullptr);
562 }
563 private:
564 std::unique_ptr<std::unordered_map<int,int> > mapping_;
565 const CpGridData* grid_ = nullptr;
566 };
567
568 } // namespace cpgrid
569} // namespace Dune
570
571#endif // OPM_INDEXSETS_HEADER
DataHandle & data
Definition: CpGridData.hpp:1166
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:570
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:458
int getGridIdx() const
Add doc/or remove method and replace it with better approach.
Definition: CpGridData.hpp:444
const CpGridData * pgrid_
Definition: Entity.hpp:329
Entity< 0 > getLevelElem() const
Get equivalent element on the level grid where the entity was born, if grid = leaf-grid-view....
Definition: Entity.hpp:629
int level() const
Return the level of the entity in the grid hierarchy. Level = 0 represents the coarsest grid.
Definition: Entity.hpp:473
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:483
typename LevelGlobalIdSet::IdType IdType
The type of the id.
Definition: Indexsets.hpp:486
void insertIdSet(const CpGridData &view)
GlobalIdSet(const CpGridData &view)
IdType id(const typename Codim< codim >::Entity &e) const
Definition: Indexsets.hpp:497
IdType subId(const typename Codim< 0 >::Entity &e, int i) const
Definition: Indexsets.hpp:509
typename Impl::CodimTraits< cd > Codim
Export supported entity types.
Definition: Indexsets.hpp:492
IdType id(const EntityType &e) const
Definition: Indexsets.hpp:503
IdType subId(const typename Codim< 0 >::Entity &e, int i, int cc) const
Definition: Indexsets.hpp:199
typename Impl::CodimTraits< cd > Codim
Export supported entity types.
Definition: Indexsets.hpp:210
IdType subId(const cpgrid::Entity< 0 > &e, int i) const
Definition: Indexsets.hpp:251
IdType idLevelZero(const Entity< codim > &e) const =delete
IdType id(const EntityType &e) const
Definition: Indexsets.hpp:230
IdSet(const CpGridData &grid)
Definition: Indexsets.hpp:212
static constexpr int dimension
Definition: Indexsets.hpp:206
IdType id(const cpgrid::Intersection &intersection) const
return id of intersection (here face number)
Definition: Indexsets.hpp:245
IdType id(const typename Codim< cd >::Entity &e) const
Definition: Indexsets.hpp:218
IdType subId(const cpgrid::Entity< 0 > &e, int i, int cc) const
IdType idLevelZero(const cpgrid::EntityRep< codim > &e) const
Definition: Indexsets.hpp:236
std::int64_t IdType
Definition: Indexsets.hpp:204
Definition: Indexsets.hpp:57
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
static constexpr int dimension
Definition: Indexsets.hpp:63
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:61
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
typename Impl::CodimTraits< cd > Codim
Export supported entity types.
Definition: Indexsets.hpp:67
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:235
Definition: Indexsets.hpp:367
void swap(std::vector< int > &cellMapping, std::vector< int > &faceMapping, std::vector< int > &pointMapping)
Definition: Indexsets.hpp:379
LevelGlobalIdSet()
Definition: Indexsets.hpp:391
IdType idLevelZero(const Entity< codim > &e) const =delete
IdType idLevelZero(const EntityRep< codim > &e) const
Definition: Indexsets.hpp:410
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:428
IdType getMaxGlobalId() const
Definition: Indexsets.hpp:465
std::int64_t IdType
Definition: Indexsets.hpp:371
static constexpr int dimension
Definition: Indexsets.hpp:373
IdType id(const EntityType &e) const
Definition: Indexsets.hpp:422
IdType id(const typename Codim< codim >::Entity &e) const
Definition: Indexsets.hpp:395
IdType getMaxCodimGlobalId() const
Definition: Indexsets.hpp:437
LevelGlobalIdSet(std::shared_ptr< const IdSet > ids, const CpGridData *view)
Definition: Indexsets.hpp:388
typename Impl::CodimTraits< cd > Codim
Export supported entity types.
Definition: Indexsets.hpp:377
Definition: Indexsets.hpp:530
ReversePointGlobalIdSet(const LevelGlobalIdSet &idSet)
Definition: Indexsets.hpp:532
int operator[](int i) const
Definition: Indexsets.hpp:546
void release()
Definition: Indexsets.hpp:559
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.
Definition: Entity.hpp:66