CpGridData.hpp
Go to the documentation of this file.
1//===========================================================================
2//
3// File: CpGridData.hpp
4//
5// Created: Sep 17 21:11:41 2013
6//
7// Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8// Bård Skaflestad <bard.skaflestad@sintef.no>
9// Markus Blatt <markus@dr-blatt.de>
10// Antonella Ritorto <antonella.ritorto@opm-op.com>
11//
12// Comment: Major parts of this file originated in dune/grid/CpGrid.hpp
13// and got transfered here during refactoring for the parallelization.
14//
15// $Date$
16//
17// $Revision$
18//
19//===========================================================================
20
21/*
22 Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
23 Copyright 2009, 2010, 2013, 2022-2023 Equinor ASA.
24 Copyright 2013 Dr. Blatt - HPC-Simulation-Software & Services
25
26 This file is part of The Open Porous Media project (OPM).
27
28 OPM is free software: you can redistribute it and/or modify
29 it under the terms of the GNU General Public License as published by
30 the Free Software Foundation, either version 3 of the License, or
31 (at your option) any later version.
32
33 OPM is distributed in the hope that it will be useful,
34 but WITHOUT ANY WARRANTY; without even the implied warranty of
35 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 GNU General Public License for more details.
37
38 You should have received a copy of the GNU General Public License
39 along with OPM. If not, see <http://www.gnu.org/licenses/>.
40*/
48#ifndef OPM_CPGRIDDATA_HEADER
49#define OPM_CPGRIDDATA_HEADER
50
51
52#include <dune/common/parallel/mpihelper.hh>
53#ifdef HAVE_DUNE_ISTL
54#include <dune/istl/owneroverlapcopy.hh>
55#endif
56
57#include <dune/common/parallel/communication.hh>
58#include <dune/common/parallel/variablesizecommunicator.hh>
59#include <dune/grid/common/gridenums.hh>
60
61#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
62#include <opm/input/eclipse/EclipseState/Grid/NNC.hpp>
63
65
67#include "CpGridDataTraits.hpp"
68//#include "DataHandleWrappers.hpp"
69//#include "GlobalIdMapping.hpp"
70#include "Geometry.hpp"
71#include "LevelHierarchy.hpp"
72
73#include <array>
74#include <initializer_list>
75#include <set>
76#include <vector>
77
78namespace Opm
79{
80class EclipseState;
81}
82namespace Dune
83{
84class CpGrid;
85
86namespace cpgrid
87{
88
89class IndexSet;
90class IdSet;
91class LevelGlobalIdSet;
92class PartitionTypeIndicator;
93template<int,int> class Geometry;
94template<int> class Entity;
95template<int> class EntityRep;
96}
97}
98
100 const std::array<int, 3>&,
101 bool);
102
103namespace Dune
104{
105namespace cpgrid
106{
107namespace mover
108{
109template<class T, int i> struct Mover;
110}
111
117{
118 template<class T, int i> friend struct mover::Mover;
119 friend class GlobalIdSet;
120 friend class HierarchicIterator;
124
125 friend
127 const std::array<int, 3>&,
128 bool);
129
130private:
131 CpGridData(const CpGridData& g);
132
133public:
134 enum{
135#ifndef MAX_DATA_COMMUNICATED_PER_ENTITY
143#else
148 MAX_DATA_PER_CELL = MAX_DATA_COMMUNICATED_PER_ENTITY
149#endif
150 };
151
152 CpGridData() = delete;
153
158 explicit CpGridData(MPIHelper::MPICommunicator comm, std::vector<std::shared_ptr<CpGridData>>& data);
159
160
161
163 explicit CpGridData(std::vector<std::shared_ptr<CpGridData>>& data);
166
167
168
169
171 int size(int codim) const;
172
174 int size (GeometryType type) const
175 {
176 if (type.isCube()) {
177 return size(3 - type.dim());
178 } else {
179 return 0;
180 }
181 }
182
198 void readEclipseFormat(const std::string& filename,
199 bool periodic_extension,
200 bool turn_normals = false,
201 bool edge_conformal = false);
202
224 void processEclipseFormat(const Opm::Deck& deck,
225 bool periodic_extension,
226 bool turn_normals = false,
227 bool clip_z = false,
228 const std::vector<double>& poreVolume = std::vector<double>{},
229 bool edge_conformal = false);
230
265 std::vector<std::size_t>
266 processEclipseFormat(const Opm::EclipseGrid* ecl_grid,
267 Opm::EclipseState* ecl_state,
268 bool periodic_extension,
269 bool turn_normals = false,
270 bool clip_z = false,
271 bool pinchActive = true,
272 bool edge_conformal = false);
273
302 void processEclipseFormat(const grdecl& input_data,
303 Opm::EclipseState* ecl_state,
304 std::array<std::set<std::pair<int, int>>, 2>& nnc,
305 bool remove_ij_boundary,
306 bool turn_normals,
307 bool pinchActive,
308 double tolerance_unique_points,
309 bool edge_conformal);
310
318 void getIJK(int c, std::array<int,3>& ijk) const;
319
320 int cellFace(int cell, int local_index) const
321 {
322 return cell_to_face_[cpgrid::EntityRep<0>(cell, true)][local_index].index();
323 }
324
325 auto cellToFace(int cellIdx) const
326 {
327 return cell_to_face_[cpgrid::EntityRep<0>(cellIdx, true)];
328 }
329
330 const auto& cellToPoint() const
331 {
332 return cell_to_point_;
333 }
334
335 const auto& cellToPoint(int cellIdx) const
336 {
337 return cell_to_point_[cellIdx];
338 }
339
340 int faceToCellSize(int face) const {
341 Dune::cpgrid::EntityRep<1> faceRep(face, true);
342 return face_to_cell_[faceRep].size();
343 }
344
345 auto faceTag(int faceIdx) const
346 {
347 Dune::cpgrid::EntityRep<1> faceRep(faceIdx, true);
348 return face_tag_[faceRep];
349 }
350
351 auto faceNormals(int faceIdx) const
352 {
353 Dune::cpgrid::EntityRep<1> faceRep(faceIdx, true);
354 return face_normals_[faceRep];
355 }
356
357 auto faceToPoint(int faceIdx) const
358 {
359 return face_to_point_[faceIdx];
360 }
361
362 int numFaces() const
363 {
364 return face_to_cell_.size();
365 }
366
367 auto cornerHistorySize() const
368 {
369 return levels_.corner_history.size();
370 }
371
372 const auto& getCornerHistory(int cornerIdx) const
373 {
374 if(cornerHistorySize()) {
375 return levels_.corner_history[cornerIdx];
376 }
377 else {
378 OPM_THROW(std::logic_error, "Vertex has no history record.\n");
379 __builtin_unreachable();
380 }
381 }
382
389 const std::vector<int>& globalCell() const
390 {
391 return global_cell_;
392 }
393
396 bool hasNNCs(const std::vector<int>& cellIndices) const;
397
411 bool mark(int refCount, const cpgrid::Entity<0>& element, bool throwOnFailure = false);
412
416 int getMark(const cpgrid::Entity<0>& element) const;
417
427 bool preAdapt();
428
430 bool adapt();
431
433 void postAdapt();
434
435private:
436 std::array<Dune::FieldVector<double,3>,8> getReferenceRefinedCorners(int idx_in_parent_cell, const std::array<int,3>& cells_per_dim) const;
437
438public:
440 int getGridIdx() const {
441 // Not the nicest way of checking if "this" points at the leaf grid view of a mixed grid (with coarse and refined cells).
442 // 1. When the grid has been refined at least onece, level_data_ptr_ ->size() >1. Therefore, there is a chance of "this" pointing at the leaf grid view.
443 // 2. Unfortunately, level_ is default initialized by 0. This implies, in particular, that if someone wants to check the value of
444 // "this->level_" when "this" points at the leaf grid view of a grid that has been refined, this value is - unfortunately - equal to 0.
445 // 3. Due to 2. we need an extra bool value to distinguish between the actual level 0 grid and such a leaf grid view (with incorrect level_ == 0). For this
446 // reason we check if child_to_parent_cells_.empty() [true for actual level 0 grid, false for the leaf grid view].
447 // --- TO BE IMPROVED ---
448 if ((levels_.level_data_ptr ->size() >1) && (levels_.level == 0) && (!levels_.child_to_parent_cells.empty())) {
449 return levels_.level_data_ptr->size() -1;
450 }
451 return levels_.level;
452 }
454 const std::vector<std::shared_ptr<Dune::cpgrid::CpGridData>>& levelData() const
455 {
456 if (levels_.level_data_ptr->empty()) {
457 OPM_THROW(std::logic_error, "Level data has not been initialized\n");
458 }
459 return *levels_.level_data_ptr;
460 }
461
469 const std::tuple<int,std::vector<int>>& getChildrenLevelAndIndexList(int elemIdx) const {
470 return levels_.parent_to_children_cells[elemIdx];
471 }
472
473 const std::vector<std::tuple<int,std::vector<int>>>& getParentToChildren() const {
474 return levels_.parent_to_children_cells;
475 }
476
478 {
479 return geometry_;
480 }
481
482 int getLeafIdxFromLevelIdx(int level_cell_idx) const
483 {
484 if (levels_.level_to_leaf_cells.empty()) {
485 OPM_THROW(std::logic_error, "Grid has no LGRs. No mapping to the leaf.\n");
486 }
487 return levels_.level_to_leaf_cells[level_cell_idx];
488 }
489
511 std::tuple< const std::shared_ptr<CpGridData>,
512 const std::vector<std::array<int,2>>> // parent_to_refined_corners(~boundary_old_to_new_corners)
513 refineSingleCell(const std::array<int,3>& cells_per_dim,
514 const int& parent_idx,
515 std::vector<std::vector<std::pair<int, std::vector<int>>>>& faceInMarkedElemAndRefinedFaces) const;
516
517 // @breif Compute center of an entity/element/cell in the Eclipse way:
518 // - Average of the 4 corners of the bottom face.
519 // - Average of the 4 corners of the top face.
520 // Return average of the previous computations.
521 // @param [in] int Index of a cell.
522 // @return 'eclipse centroid'
523 std::array<double,3> computeEclCentroid(const int idx) const;
524
525 // @breif Compute center of an entity/element/cell in the Eclipse way:
526 // - Average of the 4 corners of the bottom face.
527 // - Average of the 4 corners of the top face.
528 // Return average of the previous computations.
529 // @param [in] Entity<0> Entity
530 // @return 'eclipse centroid'
531 std::array<double,3> computeEclCentroid(const Entity<0>& elem) const;
532
533 // Make unique boundary ids for all intersections.
535
539 bool uniqueBoundaryIds() const
540 {
541 return use_unique_boundary_ids_;
542 }
543
546 void setUniqueBoundaryIds(bool uids)
547 {
548 use_unique_boundary_ids_ = uids;
549 if (use_unique_boundary_ids_ && unique_boundary_ids_.empty()) {
551 }
552 }
553
557 const std::vector<double>& zcornData() const {
558 return zcorn;
559 }
560
561
564 const IndexSet& indexSet() const
565 {
566 return *index_set_;
567 }
568
571 {
572 return *local_id_set_;
573 }
574
577 {
578 return *global_id_set_;
579 }
580
584 const std::array<int, 3>& logicalCartesianSize() const
585 {
586 return logical_cartesian_size_;
587 }
588
593 const CpGridData& view_data,
594 const std::vector<int>& cell_part);
595
601 template<class DataHandle>
602 void communicate(DataHandle& data, InterfaceType iftype, CommunicationDirection dir);
603
605
607
608 void computeCommunicationInterfaces(int noexistingPoints);
609
615
618#if HAVE_MPI
621
624
627
630
633
638 {
639 return cell_comm_;
640 }
641
646 {
647 return cell_comm_;
648 }
649
651 {
652 return cellCommunication().indexSet();
653 }
654
656 {
657 return cellCommunication().indexSet();
658 }
659
661 {
662 return cellCommunication().remoteIndices();
663 }
664
666 {
667 return cellCommunication().remoteIndices();
668 }
669#endif
670
672 const std::vector<int>& sortedNumAquiferCells() const
673 {
674 return aquifer_cells_;
675 }
676
677private:
678
680 void populateGlobalCellIndexSet();
681
682#if HAVE_MPI
683
689 template<class DataHandle>
690 void gatherData(DataHandle& data, CpGridData* global_view,
691 CpGridData* distributed_view);
692
693
700 template<int codim, class DataHandle>
701 void gatherCodimData(DataHandle& data, CpGridData* global_data,
702 CpGridData* distributed_data);
703
710 template<class DataHandle>
711 void scatterData(DataHandle& data, const CpGridData* global_data,
712 const CpGridData* distributed_data, const InterfaceMap& cell_inf,
713 const InterfaceMap& point_inf);
714
722 template<int codim, class DataHandle>
723 void scatterCodimData(DataHandle& data, CpGridData* global_data,
724 CpGridData* distributed_data);
725
734 template<int codim, class DataHandle>
735 void communicateCodim(Entity2IndexDataHandle<DataHandle, codim>& data, CommunicationDirection dir,
736 const Interface& interface);
737
746 template<int codim, class DataHandle>
747 void communicateCodim(Entity2IndexDataHandle<DataHandle, codim>& data, CommunicationDirection dir,
748 const InterfaceMap& interface);
749
750#endif
751
752 void computeGeometry(const CpGrid& grid,
753 const DefaultGeometryPolicy& globalGeometry,
754 const std::vector<int>& globalAquiferCells,
755 const OrientedEntityTable<0, 1>& globalCell2Faces,
756 DefaultGeometryPolicy& geometry,
757 std::vector<int>& aquiferCells,
759 const std::vector< std::array<int,8> >& cell2Points);
760
761 // Representing the topology
773 Opm::SparseTable<int> face_to_point_;
775 std::vector< std::array<int,8> > cell_to_point_;
782 std::array<int, 3> logical_cartesian_size_{};
789 std::vector<int> global_cell_;
795 typedef FieldVector<double, 3> PointType;
799 cpgrid::EntityVariable<int, 1> unique_boundary_ids_;
801 std::unique_ptr<cpgrid::IndexSet> index_set_;
803 std::shared_ptr<const cpgrid::IdSet> local_id_set_;
805 std::shared_ptr<LevelGlobalIdSet> global_id_set_;
807 std::shared_ptr<PartitionTypeIndicator> partition_type_indicator_;
809 LevelHierarchy levels_;
810
812 Communication ccobj_;
813
814 // Boundary information (optional).
815 bool use_unique_boundary_ids_;
816
822 std::vector<double> zcorn;
823
825 std::vector<int> aquifer_cells_;
826
827#if HAVE_MPI
828
830 CommunicationType cell_comm_;
831
833 std::tuple<Interface,Interface,Interface,Interface,Interface> cell_interfaces_;
834 /*
835 // code deactivated, because users cannot access face indices and therefore
836 // communication on faces makes no sense!
838 std::tuple<InterfaceMap,InterfaceMap,InterfaceMap,InterfaceMap,InterfaceMap>
839 face_interfaces_;
840 */
842 std::tuple<InterfaceMap,InterfaceMap,InterfaceMap,InterfaceMap,InterfaceMap>
843 point_interfaces_;
844
845#endif
846
847 // Return the geometry vector corresponding to the given codim.
848 template <int codim>
849 const EntityVariable<Geometry<3 - codim, 3>, codim>& geomVector() const
850 {
851 return geometry_.geomVector<codim>();
852 }
853
854 friend class Dune::CpGrid;
855 template<int> friend class Entity;
856 template<int> friend class EntityRep;
857 friend class Intersection;
859};
860
861
862
863#if HAVE_MPI
864
865namespace
866{
871template<class T>
872T& getInterface(InterfaceType iftype,
873 std::tuple<T,T,T,T,T>& interfaces)
874{
875 switch(iftype)
876 {
877 case 0:
878 return std::get<0>(interfaces);
879 case 1:
880 return std::get<1>(interfaces);
881 case 2:
882 return std::get<2>(interfaces);
883 case 3:
884 return std::get<3>(interfaces);
885 case 4:
886 return std::get<4>(interfaces);
887 }
888 OPM_THROW(std::runtime_error, "Invalid Interface type was used during communication");
889}
890
891} // end unnamed namespace
892
893template<int codim, class DataHandle>
894void CpGridData::communicateCodim(Entity2IndexDataHandle<DataHandle, codim>& data, CommunicationDirection dir,
895 const Interface& interface)
896{
897 this->template communicateCodim<codim>(data, dir, interface.interfaces());
898}
899
900template<int codim, class DataHandle>
901void CpGridData::communicateCodim(Entity2IndexDataHandle<DataHandle, codim>& data_wrapper, CommunicationDirection dir,
902 const InterfaceMap& interface)
903{
904 Communicator comm(ccobj_, interface);
905
906 if(dir==ForwardCommunication)
907 comm.forward(data_wrapper);
908 else
909 comm.backward(data_wrapper);
910}
911#endif
912
913template<class DataHandle>
914void CpGridData::communicate(DataHandle& data, InterfaceType iftype,
915 CommunicationDirection dir)
916{
917#if HAVE_MPI
918 if(data.contains(3,0))
919 {
920 Entity2IndexDataHandle<DataHandle, 0> data_wrapper(*this, data);
921 communicateCodim<0>(data_wrapper, dir, getInterface(iftype, cell_interfaces_));
922 }
923 if(data.contains(3,3))
924 {
925 Entity2IndexDataHandle<DataHandle, 3> data_wrapper(*this, data);
926 communicateCodim<3>(data_wrapper, dir, getInterface(iftype, point_interfaces_));
927 }
928#else
929 // Suppress warnings for unused arguments.
930 (void) data;
931 (void) iftype;
932 (void) dir;
933#endif
934}
935}}
936
937#if HAVE_MPI
940
941namespace Dune {
942namespace cpgrid {
943
944namespace mover
945{
946template<class T>
948{
950public:
951 void read(T& data)
952 {
953 data=buffer_[index_++];
954 }
955 void write(const T& data)
956 {
957 buffer_[index_++]=data;
958 }
959 void reset()
960 {
961 index_=0;
962 }
963 void resize(std::size_t size)
964 {
965 buffer_.resize(size);
966 index_=0;
967 }
968private:
969 std::vector<T> buffer_;
970 typename std::vector<T>::size_type index_;
971};
972template<class DataHandle,int codim>
973struct Mover
974{
975};
976
977template<class DataHandle>
979{
980 explicit BaseMover(DataHandle& data)
981 : data_(data)
982 {}
983 template<class E>
984 void moveData(const E& from, const E& to)
985 {
986 std::size_t size=data_.size(from);
987 buffer.resize(size);
988 data_.gather(buffer, from);
989 buffer.reset();
990 data_.scatter(buffer, to, size);
991 }
992 DataHandle& data_;
994};
995
996
997template<class DataHandle>
999{
1000 Mover(DataHandle& data, CpGridData* gatherView,
1001 CpGridData* scatterView)
1002 : BaseMover<DataHandle>(data), gatherView_(gatherView), scatterView_(scatterView)
1003 {}
1004
1005 void operator()(std::size_t from_cell_index,std::size_t to_cell_index)
1006 {
1007 Entity<0> from_entity=Entity<0>(*gatherView_, from_cell_index, true);
1008 Entity<0> to_entity=Entity<0>(*scatterView_, to_cell_index, true);
1009 this->moveData(from_entity, to_entity);
1010 }
1013};
1014
1015template<class DataHandle>
1017{
1018 Mover(DataHandle& data, CpGridData* gatherView,
1019 CpGridData* scatterView)
1020 : BaseMover<DataHandle>(data), gatherView_(gatherView), scatterView_(scatterView)
1021 {}
1022
1023 void operator()(std::size_t from_cell_index,std::size_t to_cell_index)
1024 {
1025 typedef typename OrientedEntityTable<0,1>::row_type row_type;
1026 EntityRep<0> from_cell=EntityRep<0>(from_cell_index, true);
1027 EntityRep<0> to_cell=EntityRep<0>(to_cell_index, true);
1028 const OrientedEntityTable<0,1>& table = gatherView_->cell_to_face_;
1029 row_type from_faces=table.operator[](from_cell);
1030 row_type to_faces=scatterView_->cell_to_face_[to_cell];
1031
1032 for(int i=0; i<from_faces.size(); ++i)
1033 this->moveData(from_faces[i], to_faces[i]);
1034 }
1037};
1038
1039template<class DataHandle>
1041{
1042 Mover(DataHandle& data, CpGridData* gatherView,
1043 CpGridData* scatterView)
1044 : BaseMover<DataHandle>(data), gatherView_(gatherView), scatterView_(scatterView)
1045 {}
1046 void operator()(std::size_t from_cell_index,std::size_t to_cell_index)
1047 {
1048 const std::array<int,8>& from_cell_points=
1049 gatherView_->cell_to_point_[from_cell_index];
1050 const std::array<int,8>& to_cell_points=
1051 scatterView_->cell_to_point_[to_cell_index];
1052 for(std::size_t i=0; i<8; ++i)
1053 {
1054 this->moveData(Entity<3>(*gatherView_, from_cell_points[i], true),
1055 Entity<3>(*scatterView_, to_cell_points[i], true));
1056 }
1057 }
1060};
1061
1062} // end mover namespace
1063
1064template<class DataHandle>
1065void CpGridData::scatterData(DataHandle& data, const CpGridData* global_data,
1066 const CpGridData* distributed_data, const InterfaceMap& cell_inf,
1067 const InterfaceMap& point_inf)
1068{
1069#if HAVE_MPI
1070 if(data.contains(3,0))
1071 {
1072 Entity2IndexDataHandle<DataHandle, 0> data_wrapper(*global_data, *distributed_data, data);
1073 communicateCodim<0>(data_wrapper, ForwardCommunication, cell_inf);
1074 }
1075 if(data.contains(3,3))
1076 {
1077 Entity2IndexDataHandle<DataHandle, 3> data_wrapper(*global_data, *distributed_data, data);
1078 communicateCodim<3>(data_wrapper, ForwardCommunication, point_inf);
1079 }
1080#endif
1081}
1082
1083template<int codim, class DataHandle>
1084void CpGridData::scatterCodimData(DataHandle& data, CpGridData* global_data,
1085 CpGridData* distributed_data)
1086{
1087 CpGridData *gather_view, *scatter_view;
1088 gather_view=global_data;
1089 scatter_view=distributed_data;
1090
1091 mover::Mover<DataHandle,codim> mover(data, gather_view, scatter_view);
1092
1093
1094 for(auto index=distributed_data->cellIndexSet().begin(),
1095 end = distributed_data->cellIndexSet().end();
1096 index!=end; ++index)
1097 {
1098 std::size_t from=index->global();
1099 std::size_t to=index->local();
1100 mover(from,to);
1101 }
1102}
1103
1104namespace
1105{
1106
1107template<int codim, class T, class F>
1108void visitInterior(CpGridData& distributed_data, T begin, T endit, F& func)
1109{
1110 for(T it=begin; it!=endit; ++it)
1111 {
1112 Entity<codim> entity(distributed_data, it-begin, true);
1113 PartitionType pt = entity.partitionType();
1114 if(pt==Dune::InteriorEntity)
1115 {
1116 func(*it, entity);
1117 }
1118 }
1119}
1120
1121template<class DataHandle>
1122struct GlobalIndexSizeGatherer
1123{
1124 GlobalIndexSizeGatherer(DataHandle& data_,
1125 std::vector<int>& ownedGlobalIndices_,
1126 std::vector<int>& ownedSizes_)
1127 : data(data_), ownedGlobalIndices(ownedGlobalIndices_), ownedSizes(ownedSizes_)
1128 {}
1129
1130 template<class T, class E>
1131 void operator()(T& i, E& entity)
1132 {
1133 ownedGlobalIndices.push_back(i);
1134 ownedSizes.push_back(data.size(entity));
1135 }
1136 DataHandle& data;
1137 std::vector<int>& ownedGlobalIndices;
1138 std::vector<int>& ownedSizes;
1139};
1140
1141template<class DataHandle>
1142struct DataGatherer
1143{
1144 DataGatherer(mover::MoveBuffer<typename DataHandle::DataType>& buffer_,
1145 DataHandle& data_)
1146 : buffer(buffer_), data(data_)
1147 {}
1148
1149 template<class T, class E>
1150 void operator()(T& /* it */, E& entity)
1151 {
1152 data.gather(buffer, entity);
1153 }
1154 mover::MoveBuffer<typename DataHandle::DataType>& buffer;
1155 DataHandle& data;
1156};
1157
1158}
1159
1160template<class DataHandle>
1161void CpGridData::gatherData(DataHandle& data, CpGridData* global_data,
1162 CpGridData* distributed_data)
1163{
1164#if HAVE_MPI
1165 if(data.contains(3,0))
1166 gatherCodimData<0>(data, global_data, distributed_data);
1167 if(data.contains(3,3))
1168 gatherCodimData<3>(data, global_data, distributed_data);
1169#endif
1170}
1171
1172template<int codim, class DataHandle>
1173void CpGridData::gatherCodimData(DataHandle& data, CpGridData* global_data,
1174 CpGridData* distributed_data)
1175{
1176#if HAVE_MPI
1177 // Get the mapping to global index from the global id set
1178 const std::vector<int>& mapping =
1179 distributed_data->global_id_set_->getMapping<codim>();
1180
1181 // Get the global indices and data size for the entities whose data is
1182 // to be sent, i.e. the ones that we own.
1183 std::vector<int> owned_global_indices;
1184 std::vector<int> owned_sizes;
1185 owned_global_indices.reserve(mapping.size());
1186 owned_sizes.reserve(mapping.size());
1187
1188 GlobalIndexSizeGatherer<DataHandle> gisg(data, owned_global_indices, owned_sizes);
1189 visitInterior<codim>(*distributed_data, mapping.begin(), mapping.end(), gisg);
1190
1191 // communicate the number of indices that each processor sends
1192 int no_indices=owned_sizes.size();
1193 // We will take the address of the first elemet for MPI_Allgather below.
1194 // Make sure the containers have such an element.
1195 if ( owned_global_indices.empty() )
1196 owned_global_indices.resize(1);
1197 if ( owned_sizes.empty() )
1198 owned_sizes.resize(1);
1199 std::vector<int> no_indices_to_recv(distributed_data->ccobj_.size());
1200 distributed_data->ccobj_.allgather(&no_indices, 1, &(no_indices_to_recv[0]));
1201 // compute size of the vector capable for receiving all indices
1202 // and allgather the global indices and the sizes.
1203 // calculate displacements
1204 std::vector<int> displ(distributed_data->ccobj_.size()+1, 0);
1205 std::transform(displ.begin(), displ.end()-1, no_indices_to_recv.begin(), displ.begin()+1,
1206 std::plus<int>());
1207 int global_size=displ[displ.size()-1];//+no_indices_to_recv[displ.size()-1];
1208 std::vector<int> global_indices(global_size);
1209 std::vector<int> global_sizes(global_size);
1210 MPI_Allgatherv(&(owned_global_indices[0]), no_indices, MPITraits<int>::getType(),
1211 &(global_indices[0]), &(no_indices_to_recv[0]), &(displ[0]),
1212 MPITraits<int>::getType(),
1213 distributed_data->ccobj_);
1214 MPI_Allgatherv(&(owned_sizes[0]), no_indices, MPITraits<int>::getType(),
1215 &(global_sizes[0]), &(no_indices_to_recv[0]), &(displ[0]),
1216 MPITraits<int>::getType(),
1217 distributed_data->ccobj_);
1218 std::vector<int>().swap(owned_global_indices); // free data for reuse.
1219 // Compute the number of data items to send
1220 std::vector<int> no_data_send(distributed_data->ccobj_.size());
1221 for(typename std::vector<int>::iterator begin=no_data_send.begin(),
1222 i=begin, end=no_data_send.end(); i!=end; ++i)
1223 *i = std::accumulate(global_sizes.begin()+displ[i-begin],
1224 global_sizes.begin()+displ[i-begin+1], std::size_t());
1225 // free at least some memory that can be reused.
1226 std::vector<int>().swap(owned_sizes);
1227 // compute the displacements for receiving with allgatherv
1228 displ[0]=0;
1229 std::transform(displ.begin(), displ.end()-1, no_data_send.begin(), displ.begin()+1,
1230 std::plus<std::size_t>());
1231 // Compute the number of data items we will receive
1232 int no_data_recv = displ[displ.size()-1];//+global_sizes[displ.size()-1];
1233
1234 // Collect the data to send, gather it
1235 mover::MoveBuffer<typename DataHandle::DataType> local_data_buffer, global_data_buffer;
1236 if ( no_data_send[distributed_data->ccobj_.rank()] )
1237 {
1238 local_data_buffer.resize(no_data_send[distributed_data->ccobj_.rank()]);
1239 }
1240 else
1241 {
1242 local_data_buffer.resize(1);
1243 }
1244 global_data_buffer.resize(no_data_recv);
1245
1246 DataGatherer<DataHandle> gatherer(local_data_buffer, data);
1247 visitInterior<codim>(*distributed_data, mapping.begin(), mapping.end(), gatherer);
1248 MPI_Allgatherv(&(local_data_buffer.buffer_[0]), no_data_send[distributed_data->ccobj_.rank()],
1249 MPITraits<typename DataHandle::DataType>::getType(),
1250 &(global_data_buffer.buffer_[0]), &(no_data_send[0]), &(displ[0]),
1251 MPITraits<typename DataHandle::DataType>::getType(),
1252 distributed_data->ccobj_);
1253 Entity2IndexDataHandle<DataHandle, codim> edata(*global_data, data);
1254 int offset=0;
1255 for(int i=0; i< codim; ++i)
1256 offset+=global_data->size(i);
1257
1258 typename std::vector<int>::const_iterator s=global_sizes.begin();
1259 for(typename std::vector<int>::const_iterator i=global_indices.begin(),
1260 end=global_indices.end();
1261 i!=end; ++s, ++i)
1262 {
1263 edata.scatter(global_data_buffer, *i-offset, *s);
1264 }
1265#endif
1266}
1267
1268} // end namespace cpgrid
1269} // end namespace Dune
1270
1271#endif
1272
1273#endif
DataHandle & data
Definition: CpGridData.hpp:1136
mover::MoveBuffer< typename DataHandle::DataType > & buffer
Definition: CpGridData.hpp:1154
std::vector< int > & ownedGlobalIndices
Definition: CpGridData.hpp:1137
void refine_and_check(const Dune::cpgrid::Geometry< 3, 3 > &, const std::array< int, 3 > &, bool)
std::vector< int > & ownedSizes
Definition: CpGridData.hpp:1138
[ provides Dune::Grid ]
Definition: CpGrid.hpp:204
Struct that hods all the data needed to represent a Cpgrid.
Definition: CpGridData.hpp:117
auto faceToPoint(int faceIdx) const
Definition: CpGridData.hpp:357
void processEclipseFormat(const grdecl &input_data, Opm::EclipseState *ecl_state, std::array< std::set< std::pair< int, int > >, 2 > &nnc, bool remove_ij_boundary, bool turn_normals, bool pinchActive, double tolerance_unique_points, bool edge_conformal)
void postAdapt()
Clean up refinement/coarsening markers - set every element to the mark 0 which represents 'doing noth...
const cpgrid::LevelGlobalIdSet & globalIdSet() const
Get the global index set.
Definition: CpGridData.hpp:576
CpGridDataTraits::CommunicationType CommunicationType
type of OwnerOverlap communication for cells
Definition: CpGridData.hpp:626
@ MAX_DATA_PER_CELL
The maximum data items allowed per cell (DUNE < 2.5.2)
Definition: CpGridData.hpp:142
CpGridDataTraits::ParallelIndexSet ParallelIndexSet
The type of the parallel index set.
Definition: CpGridData.hpp:629
int size(GeometryType type) const
number of leaf entities per geometry type in this process
Definition: CpGridData.hpp:174
const std::array< int, 3 > & logicalCartesianSize() const
Definition: CpGridData.hpp:584
void processEclipseFormat(const Opm::Deck &deck, bool periodic_extension, bool turn_normals=false, bool clip_z=false, const std::vector< double > &poreVolume=std::vector< double >{}, bool edge_conformal=false)
void communicate(DataHandle &data, InterfaceType iftype, CommunicationDirection dir)
communicate objects for all codims on a given level
Definition: CpGridData.hpp:914
auto faceTag(int faceIdx) const
Definition: CpGridData.hpp:345
bool uniqueBoundaryIds() const
Definition: CpGridData.hpp:539
const std::tuple< int, std::vector< int > > & getChildrenLevelAndIndexList(int elemIdx) const
Retrieves the level and child indices of a given parent cell.
Definition: CpGridData.hpp:469
std::array< double, 3 > computeEclCentroid(const Entity< 0 > &elem) const
void computeCommunicationInterfaces(int noexistingPoints)
int getLeafIdxFromLevelIdx(int level_cell_idx) const
Definition: CpGridData.hpp:482
const auto & getCornerHistory(int cornerIdx) const
Definition: CpGridData.hpp:372
RemoteIndices & cellRemoteIndices()
Definition: CpGridData.hpp:660
int size(int codim) const
number of leaf entities per codim in this process
void readEclipseFormat(const std::string &filename, bool periodic_extension, bool turn_normals=false, bool edge_conformal=false)
CpGridDataTraits::CollectiveCommunication CollectiveCommunication
Definition: CpGridData.hpp:614
const std::vector< int > & globalCell() const
Definition: CpGridData.hpp:389
CpGridDataTraits::InterfaceMap InterfaceMap
The type of the map describing communication interfaces.
Definition: CpGridData.hpp:623
CpGridDataTraits::Communication Communication
The type of the collective communication.
Definition: CpGridData.hpp:613
int numFaces() const
Definition: CpGridData.hpp:362
const std::vector< std::tuple< int, std::vector< int > > > & getParentToChildren() const
Definition: CpGridData.hpp:473
void getIJK(int c, std::array< int, 3 > &ijk) const
Extract Cartesian index triplet (i,j,k) of an active cell.
const IndexSet & indexSet() const
Definition: CpGridData.hpp:564
CommunicationType & cellCommunication()
Get the owner-overlap-copy communication for cells.
Definition: CpGridData.hpp:637
auto cellToFace(int cellIdx) const
Definition: CpGridData.hpp:325
auto faceNormals(int faceIdx) const
Definition: CpGridData.hpp:351
CpGridDataTraits::RemoteIndices RemoteIndices
The type of the remote indices information.
Definition: CpGridData.hpp:632
auto cornerHistorySize() const
Definition: CpGridData.hpp:367
ParallelIndexSet & cellIndexSet()
Definition: CpGridData.hpp:650
const auto & cellToPoint(int cellIdx) const
Definition: CpGridData.hpp:335
int getMark(const cpgrid::Entity< 0 > &element) const
Return refinement mark for entity.
const ParallelIndexSet & cellIndexSet() const
Definition: CpGridData.hpp:655
CpGridDataTraits::MPICommunicator MPICommunicator
The type of the mpi communicator.
Definition: CpGridData.hpp:611
bool mark(int refCount, const cpgrid::Entity< 0 > &element, bool throwOnFailure=false)
Mark entity for refinement or coarsening.
CpGridData(std::vector< std::shared_ptr< CpGridData > > &data)
Constructor.
void distributeGlobalGrid(CpGrid &grid, const CpGridData &view_data, const std::vector< int > &cell_part)
Redistribute a global grid.
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:454
const auto & cellToPoint() const
Definition: CpGridData.hpp:330
const std::vector< double > & zcornData() const
Definition: CpGridData.hpp:557
void setUniqueBoundaryIds(bool uids)
Definition: CpGridData.hpp:546
bool preAdapt()
Set mightVanish flags for elements that will be refined in the next adapt() call Need to be called af...
int getGridIdx() const
Add doc/or remove method and replace it with better approach.
Definition: CpGridData.hpp:440
bool hasNNCs(const std::vector< int > &cellIndices) const
Check all cells selected for refinement have no NNCs (no neighbor connections). Assumption: all grid ...
const CommunicationType & cellCommunication() const
Get the owner-overlap-copy communication for cells.
Definition: CpGridData.hpp:645
int cellFace(int cell, int local_index) const
Definition: CpGridData.hpp:320
const cpgrid::IdSet & localIdSet() const
Get the local index set.
Definition: CpGridData.hpp:570
const cpgrid::DefaultGeometryPolicy getGeometry() const
Definition: CpGridData.hpp:477
bool adapt()
TO DO: Documentation. Triggers the grid refinement process - Currently, returns preAdapt()
int faceToCellSize(int face) const
Definition: CpGridData.hpp:340
std::vector< std::size_t > processEclipseFormat(const Opm::EclipseGrid *ecl_grid, Opm::EclipseState *ecl_state, bool periodic_extension, bool turn_normals=false, bool clip_z=false, bool pinchActive=true, bool edge_conformal=false)
CpGridDataTraits::Communicator Communicator
The type of the Communicator.
Definition: CpGridData.hpp:620
std::tuple< const std::shared_ptr< CpGridData >, const std::vector< std::array< int, 2 > > > refineSingleCell(const std::array< int, 3 > &cells_per_dim, const int &parent_idx, std::vector< std::vector< std::pair< int, std::vector< int > > > > &faceInMarkedElemAndRefinedFaces) const
Refine a single cell and return a shared pointer of CpGridData type.
std::array< double, 3 > computeEclCentroid(const int idx) const
const std::vector< int > & sortedNumAquiferCells() const
Get sorted active cell indices of numerical aquifer.
Definition: CpGridData.hpp:672
const RemoteIndices & cellRemoteIndices() const
Definition: CpGridData.hpp:665
CpGridData(MPIHelper::MPICommunicator comm, std::vector< std::shared_ptr< CpGridData > > &data)
Definition: DefaultGeometryPolicy.hpp:53
const EntityVariable< cpgrid::Geometry< 3 - codim, 3 >, codim > & geomVector() const
Definition: DefaultGeometryPolicy.hpp:86
Wrapper that turns a data handle suitable for dune-grid into one based on integers instead of entitie...
Definition: Entity2IndexDataHandle.hpp:56
Represents an entity of a given codim, with positive or negative orientation.
Definition: EntityRep.hpp:98
The global id set for Dune.
Definition: Indexsets.hpp:483
Only needs to provide interface for doing nothing.
Definition: Iterators.hpp:118
Definition: Indexsets.hpp:199
Definition: Indexsets.hpp:57
Definition: Intersection.hpp:63
Definition: Indexsets.hpp:367
Definition: PartitionTypeIndicator.hpp:50
Definition: CpGridData.hpp:948
void write(const T &data)
Definition: CpGridData.hpp:955
void reset()
Definition: CpGridData.hpp:959
void read(T &data)
Definition: CpGridData.hpp:951
void resize(std::size_t size)
Definition: CpGridData.hpp:963
The namespace Dune is the main namespace for all Dune code.
Definition: common/CartesianIndexMapper.hpp:10
Dune::cpgrid::Cell2FacesContainer cell2Faces(const Dune::CpGrid &grid)
Get the cell to faces mapping of a grid.
Holds the implementation of the CpGrid as a pimple.
Definition: CellQuadrature.hpp:26
MPIHelper::MPICommunicator MPICommunicator
The type of the collective communication.
Definition: CpGridDataTraits.hpp:56
Dune::VariableSizeCommunicator<> Communicator
The type of the Communicator.
Definition: CpGridDataTraits.hpp:71
Dune::RemoteIndices< ParallelIndexSet > RemoteIndices
The type of the remote indices information.
Definition: CpGridDataTraits.hpp:83
typename CommunicationType::ParallelIndexSet ParallelIndexSet
The type of the parallel index set.
Definition: CpGridDataTraits.hpp:80
Dune::Communication< MPICommunicator > CollectiveCommunication
Definition: CpGridDataTraits.hpp:59
Dune::OwnerOverlapCopyCommunication< int, int > CommunicationType
type of OwnerOverlap communication for cells
Definition: CpGridDataTraits.hpp:77
Dune::Communication< MPICommunicator > Communication
Definition: CpGridDataTraits.hpp:58
AttributeSet
The type of the set of the attributes.
Definition: CpGridDataTraits.hpp:66
Communicator::InterfaceMap InterfaceMap
The type of the map describing communication interfaces.
Definition: CpGridDataTraits.hpp:74
std::vector< std::shared_ptr< CpGridData > > * level_data_ptr
Definition: LevelHierarchy.hpp:65
std::vector< std::array< int, 2 > > child_to_parent_cells
Definition: LevelHierarchy.hpp:80
std::vector< int > level_to_leaf_cells
Definition: LevelHierarchy.hpp:68
std::vector< std::tuple< int, std::vector< int > > > parent_to_children_cells
Definition: LevelHierarchy.hpp:70
int level
Definition: LevelHierarchy.hpp:63
std::vector< std::array< int, 2 > > corner_history
Definition: LevelHierarchy.hpp:77
Definition: CpGridData.hpp:979
BaseMover(DataHandle &data)
Definition: CpGridData.hpp:980
void moveData(const E &from, const E &to)
Definition: CpGridData.hpp:984
MoveBuffer< typename DataHandle::DataType > buffer
Definition: CpGridData.hpp:993
DataHandle & data_
Definition: CpGridData.hpp:992
Definition: CpGridData.hpp:999
void operator()(std::size_t from_cell_index, std::size_t to_cell_index)
Definition: CpGridData.hpp:1005
CpGridData * scatterView_
Definition: CpGridData.hpp:1012
CpGridData * gatherView_
Definition: CpGridData.hpp:1011
Mover(DataHandle &data, CpGridData *gatherView, CpGridData *scatterView)
Definition: CpGridData.hpp:1000
Definition: CpGridData.hpp:1017
Mover(DataHandle &data, CpGridData *gatherView, CpGridData *scatterView)
Definition: CpGridData.hpp:1018
CpGridData * gatherView_
Definition: CpGridData.hpp:1035
CpGridData * scatterView_
Definition: CpGridData.hpp:1036
void operator()(std::size_t from_cell_index, std::size_t to_cell_index)
Definition: CpGridData.hpp:1023
Definition: CpGridData.hpp:1041
CpGridData * scatterView_
Definition: CpGridData.hpp:1059
CpGridData * gatherView_
Definition: CpGridData.hpp:1058
Mover(DataHandle &data, CpGridData *gatherView, CpGridData *scatterView)
Definition: CpGridData.hpp:1042
void operator()(std::size_t from_cell_index, std::size_t to_cell_index)
Definition: CpGridData.hpp:1046
Definition: CpGridData.hpp:974
Definition: preprocess.h:56