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
72#include <array>
73#include <initializer_list>
74#include <set>
75#include <vector>
76
77namespace Opm
78{
79class EclipseState;
80}
81namespace Dune
82{
83class CpGrid;
84
85namespace cpgrid
86{
87
88class IndexSet;
89class IdSet;
90class LevelGlobalIdSet;
91class PartitionTypeIndicator;
92template<int,int> class Geometry;
93template<int> class Entity;
94template<int> class EntityRep;
95}
96}
97
99 const std::array<int, 3>&,
100 bool);
101
102namespace Dune
103{
104namespace cpgrid
105{
106namespace mover
107{
108template<class T, int i> struct Mover;
109}
110
116{
117 template<class T, int i> friend struct mover::Mover;
118 friend class GlobalIdSet;
119 friend class HierarchicIterator;
123
124 friend
126 const std::array<int, 3>&,
127 bool);
128
129private:
130 CpGridData(const CpGridData& g);
131
132public:
133 enum{
134#ifndef MAX_DATA_COMMUNICATED_PER_ENTITY
142#else
147 MAX_DATA_PER_CELL = MAX_DATA_COMMUNICATED_PER_ENTITY
148#endif
149 };
150
151 CpGridData() = delete;
152
157 explicit CpGridData(MPIHelper::MPICommunicator comm, std::vector<std::shared_ptr<CpGridData>>& data);
158
159
160
162 explicit CpGridData(std::vector<std::shared_ptr<CpGridData>>& data);
165
166
167
168
170 int size(int codim) const;
171
173 int size (GeometryType type) const
174 {
175 if (type.isCube()) {
176 return size(3 - type.dim());
177 } else {
178 return 0;
179 }
180 }
181
197 void readEclipseFormat(const std::string& filename,
198 bool periodic_extension,
199 bool turn_normals = false,
200 bool edge_conformal = false);
201
223 void processEclipseFormat(const Opm::Deck& deck,
224 bool periodic_extension,
225 bool turn_normals = false,
226 bool clip_z = false,
227 const std::vector<double>& poreVolume = std::vector<double>{},
228 bool edge_conformal = false);
229
264 std::vector<std::size_t>
265 processEclipseFormat(const Opm::EclipseGrid* ecl_grid,
266 Opm::EclipseState* ecl_state,
267 bool periodic_extension,
268 bool turn_normals = false,
269 bool clip_z = false,
270 bool pinchActive = true,
271 bool edge_conformal = false);
272
301 void processEclipseFormat(const grdecl& input_data,
302 Opm::EclipseState* ecl_state,
303 std::array<std::set<std::pair<int, int>>, 2>& nnc,
304 bool remove_ij_boundary,
305 bool turn_normals,
306 bool pinchActive,
307 double tolerance_unique_points,
308 bool edge_conformal);
309
317 void getIJK(int c, std::array<int,3>& ijk) const;
318
319 int cellFace(int cell, int local_index) const
320 {
321 return cell_to_face_[cpgrid::EntityRep<0>(cell, true)][local_index].index();
322 }
323
324 auto cellToFace(int cellIdx) const
325 {
326 return cell_to_face_[cpgrid::EntityRep<0>(cellIdx, true)];
327 }
328
329 const auto& cellToPoint() const
330 {
331 return cell_to_point_;
332 }
333
334 const auto& cellToPoint(int cellIdx) const
335 {
336 return cell_to_point_[cellIdx];
337 }
338
339 int faceToCellSize(int face) const {
340 Dune::cpgrid::EntityRep<1> faceRep(face, true);
341 return face_to_cell_[faceRep].size();
342 }
343
344 auto faceTag(int faceIdx) const
345 {
346 Dune::cpgrid::EntityRep<1> faceRep(faceIdx, true);
347 return face_tag_[faceRep];
348 }
349
350 auto faceNormals(int faceIdx) const
351 {
352 Dune::cpgrid::EntityRep<1> faceRep(faceIdx, true);
353 return face_normals_[faceRep];
354 }
355
356 auto faceToPoint(int faceIdx) const
357 {
358 return face_to_point_[faceIdx];
359 }
360
361 int numFaces() const
362 {
363 return face_to_cell_.size();
364 }
365
366 auto cornerHistorySize() const
367 {
368 return corner_history_.size();
369 }
370
371 const auto& getCornerHistory(int cornerIdx) const
372 {
373 if(cornerHistorySize()) {
374 return corner_history_[cornerIdx];
375 }
376 else {
377 OPM_THROW(std::logic_error, "Vertex has no history record.\n");
378 __builtin_unreachable();
379 }
380 }
381
388 const std::vector<int>& globalCell() const
389 {
390 return global_cell_;
391 }
392
395 bool hasNNCs(const std::vector<int>& cellIndices) const;
396
410 bool mark(int refCount, const cpgrid::Entity<0>& element, bool throwOnFailure = false);
411
415 int getMark(const cpgrid::Entity<0>& element) const;
416
426 bool preAdapt();
427
429 bool adapt();
430
432 void postAdapt();
433
434private:
435 std::array<Dune::FieldVector<double,3>,8> getReferenceRefinedCorners(int idx_in_parent_cell, const std::array<int,3>& cells_per_dim) const;
436
437public:
439 int getGridIdx() const {
440 // Not the nicest way of checking if "this" points at the leaf grid view of a mixed grid (with coarse and refined cells).
441 // 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.
442 // 2. Unfortunately, level_ is default initialized by 0. This implies, in particular, that if someone wants to check the value of
443 // "this->level_" when "this" points at the leaf grid view of a grid that has been refined, this value is - unfortunately - equal to 0.
444 // 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
445 // reason we check if child_to_parent_cells_.empty() [true for actual level 0 grid, false for the leaf grid view].
446 // --- TO BE IMPROVED ---
447 if ((level_data_ptr_ ->size() >1) && (level_ == 0) && (!child_to_parent_cells_.empty())) {
448 return level_data_ptr_->size() -1;
449 }
450 return level_;
451 }
453 const std::vector<std::shared_ptr<Dune::cpgrid::CpGridData>>& levelData() const
454 {
455 if (level_data_ptr_->empty()) {
456 OPM_THROW(std::logic_error, "Level data has not been initialized\n");
457 }
458 return *level_data_ptr_;
459 }
460
468 const std::tuple<int,std::vector<int>>& getChildrenLevelAndIndexList(int elemIdx) const {
469 return parent_to_children_cells_[elemIdx];
470 }
471
472 const std::vector<std::tuple<int,std::vector<int>>>& getParentToChildren() const {
473 return parent_to_children_cells_;
474 }
475
477 {
478 return geometry_;
479 }
480
481 int getLeafIdxFromLevelIdx(int level_cell_idx) const
482 {
483 if (level_to_leaf_cells_.empty()) {
484 OPM_THROW(std::logic_error, "Grid has no LGRs. No mapping to the leaf.\n");
485 }
486 return level_to_leaf_cells_[level_cell_idx];
487 }
488
510 std::tuple< const std::shared_ptr<CpGridData>,
511 const std::vector<std::array<int,2>>> // parent_to_refined_corners(~boundary_old_to_new_corners)
512 refineSingleCell(const std::array<int,3>& cells_per_dim,
513 const int& parent_idx,
514 std::vector<std::vector<std::pair<int, std::vector<int>>>>& faceInMarkedElemAndRefinedFaces) const;
515
516 // @breif Compute center of an entity/element/cell in the Eclipse way:
517 // - Average of the 4 corners of the bottom face.
518 // - Average of the 4 corners of the top face.
519 // Return average of the previous computations.
520 // @param [in] int Index of a cell.
521 // @return 'eclipse centroid'
522 std::array<double,3> computeEclCentroid(const int idx) const;
523
524 // @breif Compute center of an entity/element/cell in the Eclipse way:
525 // - Average of the 4 corners of the bottom face.
526 // - Average of the 4 corners of the top face.
527 // Return average of the previous computations.
528 // @param [in] Entity<0> Entity
529 // @return 'eclipse centroid'
530 std::array<double,3> computeEclCentroid(const Entity<0>& elem) const;
531
532 // Make unique boundary ids for all intersections.
534
538 bool uniqueBoundaryIds() const
539 {
540 return use_unique_boundary_ids_;
541 }
542
545 void setUniqueBoundaryIds(bool uids)
546 {
547 use_unique_boundary_ids_ = uids;
548 if (use_unique_boundary_ids_ && unique_boundary_ids_.empty()) {
550 }
551 }
552
556 const std::vector<double>& zcornData() const {
557 return zcorn;
558 }
559
560
563 const IndexSet& indexSet() const
564 {
565 return *index_set_;
566 }
567
570 {
571 return *local_id_set_;
572 }
573
576 {
577 return *global_id_set_;
578 }
579
583 const std::array<int, 3>& logicalCartesianSize() const
584 {
585 return logical_cartesian_size_;
586 }
587
592 const CpGridData& view_data,
593 const std::vector<int>& cell_part);
594
600 template<class DataHandle>
601 void communicate(DataHandle& data, InterfaceType iftype, CommunicationDirection dir);
602
604
606
607 void computeCommunicationInterfaces(int noexistingPoints);
608
614
617#if HAVE_MPI
620
623
626
629
632
637 {
638 return cell_comm_;
639 }
640
645 {
646 return cell_comm_;
647 }
648
650 {
651 return cellCommunication().indexSet();
652 }
653
655 {
656 return cellCommunication().indexSet();
657 }
658
660 {
661 return cellCommunication().remoteIndices();
662 }
663
665 {
666 return cellCommunication().remoteIndices();
667 }
668#endif
669
671 const std::vector<int>& sortedNumAquiferCells() const
672 {
673 return aquifer_cells_;
674 }
675
676private:
677
679 void populateGlobalCellIndexSet();
680
681#if HAVE_MPI
682
688 template<class DataHandle>
689 void gatherData(DataHandle& data, CpGridData* global_view,
690 CpGridData* distributed_view);
691
692
699 template<int codim, class DataHandle>
700 void gatherCodimData(DataHandle& data, CpGridData* global_data,
701 CpGridData* distributed_data);
702
709 template<class DataHandle>
710 void scatterData(DataHandle& data, const CpGridData* global_data,
711 const CpGridData* distributed_data, const InterfaceMap& cell_inf,
712 const InterfaceMap& point_inf);
713
721 template<int codim, class DataHandle>
722 void scatterCodimData(DataHandle& data, CpGridData* global_data,
723 CpGridData* distributed_data);
724
733 template<int codim, class DataHandle>
734 void communicateCodim(Entity2IndexDataHandle<DataHandle, codim>& data, CommunicationDirection dir,
735 const Interface& interface);
736
745 template<int codim, class DataHandle>
746 void communicateCodim(Entity2IndexDataHandle<DataHandle, codim>& data, CommunicationDirection dir,
747 const InterfaceMap& interface);
748
749#endif
750
751 void computeGeometry(const CpGrid& grid,
752 const DefaultGeometryPolicy& globalGeometry,
753 const std::vector<int>& globalAquiferCells,
754 const OrientedEntityTable<0, 1>& globalCell2Faces,
755 DefaultGeometryPolicy& geometry,
756 std::vector<int>& aquiferCells,
758 const std::vector< std::array<int,8> >& cell2Points);
759
760 // Representing the topology
772 Opm::SparseTable<int> face_to_point_;
774 std::vector< std::array<int,8> > cell_to_point_;
781 std::array<int, 3> logical_cartesian_size_{};
788 std::vector<int> global_cell_;
794 typedef FieldVector<double, 3> PointType;
798 cpgrid::EntityVariable<int, 1> unique_boundary_ids_;
800 std::unique_ptr<cpgrid::IndexSet> index_set_;
802 std::shared_ptr<const cpgrid::IdSet> local_id_set_;
804 std::shared_ptr<LevelGlobalIdSet> global_id_set_;
806 std::shared_ptr<PartitionTypeIndicator> partition_type_indicator_;
808 std::vector<int> mark_;
810 int level_{0};
812 std::vector<std::shared_ptr<CpGridData>>* level_data_ptr_;
813 // SUITABLE FOR ALL LEVELS EXCEPT FOR LEAFVIEW
815 std::vector<int> level_to_leaf_cells_; // In entry 'level cell index', we store 'leafview cell index' // {level LGR, {child0, child1, ...}}
817 std::vector<std::tuple<int,std::vector<int>>> parent_to_children_cells_; // {# children in x-direction, ... y-, ... z-}
819 std::array<int,3> cells_per_dim_;
820 // SUITABLE ONLY FOR LEAFVIEW // {level, cell index in that level}
822 std::vector<std::array<int,2>> leaf_to_level_cells_;
824 std::vector<std::array<int,2>> corner_history_;
825 // SUITABLE FOR ALL LEVELS INCLUDING LEAFVIEW // {level parent cell, parent cell index}
827 std::vector<std::array<int,2>> child_to_parent_cells_;
830 std::vector<int> cell_to_idxInParentCell_;
832 int refinement_max_level_{0};
833
835 Communication ccobj_;
836
837 // Boundary information (optional).
838 bool use_unique_boundary_ids_;
839
845 std::vector<double> zcorn;
846
848 std::vector<int> aquifer_cells_;
849
850#if HAVE_MPI
851
853 CommunicationType cell_comm_;
854
856 std::tuple<Interface,Interface,Interface,Interface,Interface> cell_interfaces_;
857 /*
858 // code deactivated, because users cannot access face indices and therefore
859 // communication on faces makes no sense!
861 std::tuple<InterfaceMap,InterfaceMap,InterfaceMap,InterfaceMap,InterfaceMap>
862 face_interfaces_;
863 */
865 std::tuple<InterfaceMap,InterfaceMap,InterfaceMap,InterfaceMap,InterfaceMap>
866 point_interfaces_;
867
868#endif
869
870 // Return the geometry vector corresponding to the given codim.
871 template <int codim>
872 const EntityVariable<Geometry<3 - codim, 3>, codim>& geomVector() const
873 {
874 return geometry_.geomVector<codim>();
875 }
876
877 friend class Dune::CpGrid;
878 template<int> friend class Entity;
879 template<int> friend class EntityRep;
880 friend class Intersection;
882};
883
884
885
886#if HAVE_MPI
887
888namespace
889{
894template<class T>
895T& getInterface(InterfaceType iftype,
896 std::tuple<T,T,T,T,T>& interfaces)
897{
898 switch(iftype)
899 {
900 case 0:
901 return std::get<0>(interfaces);
902 case 1:
903 return std::get<1>(interfaces);
904 case 2:
905 return std::get<2>(interfaces);
906 case 3:
907 return std::get<3>(interfaces);
908 case 4:
909 return std::get<4>(interfaces);
910 }
911 OPM_THROW(std::runtime_error, "Invalid Interface type was used during communication");
912}
913
914} // end unnamed namespace
915
916template<int codim, class DataHandle>
917void CpGridData::communicateCodim(Entity2IndexDataHandle<DataHandle, codim>& data, CommunicationDirection dir,
918 const Interface& interface)
919{
920 this->template communicateCodim<codim>(data, dir, interface.interfaces());
921}
922
923template<int codim, class DataHandle>
924void CpGridData::communicateCodim(Entity2IndexDataHandle<DataHandle, codim>& data_wrapper, CommunicationDirection dir,
925 const InterfaceMap& interface)
926{
927 Communicator comm(ccobj_, interface);
928
929 if(dir==ForwardCommunication)
930 comm.forward(data_wrapper);
931 else
932 comm.backward(data_wrapper);
933}
934#endif
935
936template<class DataHandle>
937void CpGridData::communicate(DataHandle& data, InterfaceType iftype,
938 CommunicationDirection dir)
939{
940#if HAVE_MPI
941 if(data.contains(3,0))
942 {
943 Entity2IndexDataHandle<DataHandle, 0> data_wrapper(*this, data);
944 communicateCodim<0>(data_wrapper, dir, getInterface(iftype, cell_interfaces_));
945 }
946 if(data.contains(3,3))
947 {
948 Entity2IndexDataHandle<DataHandle, 3> data_wrapper(*this, data);
949 communicateCodim<3>(data_wrapper, dir, getInterface(iftype, point_interfaces_));
950 }
951#else
952 // Suppress warnings for unused arguments.
953 (void) data;
954 (void) iftype;
955 (void) dir;
956#endif
957}
958}}
959
960#if HAVE_MPI
963
964namespace Dune {
965namespace cpgrid {
966
967namespace mover
968{
969template<class T>
971{
973public:
974 void read(T& data)
975 {
976 data=buffer_[index_++];
977 }
978 void write(const T& data)
979 {
980 buffer_[index_++]=data;
981 }
982 void reset()
983 {
984 index_=0;
985 }
986 void resize(std::size_t size)
987 {
988 buffer_.resize(size);
989 index_=0;
990 }
991private:
992 std::vector<T> buffer_;
993 typename std::vector<T>::size_type index_;
994};
995template<class DataHandle,int codim>
996struct Mover
997{
998};
999
1000template<class DataHandle>
1002{
1003 explicit BaseMover(DataHandle& data)
1004 : data_(data)
1005 {}
1006 template<class E>
1007 void moveData(const E& from, const E& to)
1008 {
1009 std::size_t size=data_.size(from);
1010 buffer.resize(size);
1011 data_.gather(buffer, from);
1012 buffer.reset();
1013 data_.scatter(buffer, to, size);
1014 }
1015 DataHandle& data_;
1017};
1018
1019
1020template<class DataHandle>
1022{
1023 Mover(DataHandle& data, CpGridData* gatherView,
1024 CpGridData* scatterView)
1025 : BaseMover<DataHandle>(data), gatherView_(gatherView), scatterView_(scatterView)
1026 {}
1027
1028 void operator()(std::size_t from_cell_index,std::size_t to_cell_index)
1029 {
1030 Entity<0> from_entity=Entity<0>(*gatherView_, from_cell_index, true);
1031 Entity<0> to_entity=Entity<0>(*scatterView_, to_cell_index, true);
1032 this->moveData(from_entity, to_entity);
1033 }
1036};
1037
1038template<class DataHandle>
1040{
1041 Mover(DataHandle& data, CpGridData* gatherView,
1042 CpGridData* scatterView)
1043 : BaseMover<DataHandle>(data), gatherView_(gatherView), scatterView_(scatterView)
1044 {}
1045
1046 void operator()(std::size_t from_cell_index,std::size_t to_cell_index)
1047 {
1048 typedef typename OrientedEntityTable<0,1>::row_type row_type;
1049 EntityRep<0> from_cell=EntityRep<0>(from_cell_index, true);
1050 EntityRep<0> to_cell=EntityRep<0>(to_cell_index, true);
1051 const OrientedEntityTable<0,1>& table = gatherView_->cell_to_face_;
1052 row_type from_faces=table.operator[](from_cell);
1053 row_type to_faces=scatterView_->cell_to_face_[to_cell];
1054
1055 for(int i=0; i<from_faces.size(); ++i)
1056 this->moveData(from_faces[i], to_faces[i]);
1057 }
1060};
1061
1062template<class DataHandle>
1064{
1065 Mover(DataHandle& data, CpGridData* gatherView,
1066 CpGridData* scatterView)
1067 : BaseMover<DataHandle>(data), gatherView_(gatherView), scatterView_(scatterView)
1068 {}
1069 void operator()(std::size_t from_cell_index,std::size_t to_cell_index)
1070 {
1071 const std::array<int,8>& from_cell_points=
1072 gatherView_->cell_to_point_[from_cell_index];
1073 const std::array<int,8>& to_cell_points=
1074 scatterView_->cell_to_point_[to_cell_index];
1075 for(std::size_t i=0; i<8; ++i)
1076 {
1077 this->moveData(Entity<3>(*gatherView_, from_cell_points[i], true),
1078 Entity<3>(*scatterView_, to_cell_points[i], true));
1079 }
1080 }
1083};
1084
1085} // end mover namespace
1086
1087template<class DataHandle>
1088void CpGridData::scatterData(DataHandle& data, const CpGridData* global_data,
1089 const CpGridData* distributed_data, const InterfaceMap& cell_inf,
1090 const InterfaceMap& point_inf)
1091{
1092#if HAVE_MPI
1093 if(data.contains(3,0))
1094 {
1095 Entity2IndexDataHandle<DataHandle, 0> data_wrapper(*global_data, *distributed_data, data);
1096 communicateCodim<0>(data_wrapper, ForwardCommunication, cell_inf);
1097 }
1098 if(data.contains(3,3))
1099 {
1100 Entity2IndexDataHandle<DataHandle, 3> data_wrapper(*global_data, *distributed_data, data);
1101 communicateCodim<3>(data_wrapper, ForwardCommunication, point_inf);
1102 }
1103#endif
1104}
1105
1106template<int codim, class DataHandle>
1107void CpGridData::scatterCodimData(DataHandle& data, CpGridData* global_data,
1108 CpGridData* distributed_data)
1109{
1110 CpGridData *gather_view, *scatter_view;
1111 gather_view=global_data;
1112 scatter_view=distributed_data;
1113
1114 mover::Mover<DataHandle,codim> mover(data, gather_view, scatter_view);
1115
1116
1117 for(auto index=distributed_data->cellIndexSet().begin(),
1118 end = distributed_data->cellIndexSet().end();
1119 index!=end; ++index)
1120 {
1121 std::size_t from=index->global();
1122 std::size_t to=index->local();
1123 mover(from,to);
1124 }
1125}
1126
1127namespace
1128{
1129
1130template<int codim, class T, class F>
1131void visitInterior(CpGridData& distributed_data, T begin, T endit, F& func)
1132{
1133 for(T it=begin; it!=endit; ++it)
1134 {
1135 Entity<codim> entity(distributed_data, it-begin, true);
1136 PartitionType pt = entity.partitionType();
1137 if(pt==Dune::InteriorEntity)
1138 {
1139 func(*it, entity);
1140 }
1141 }
1142}
1143
1144template<class DataHandle>
1145struct GlobalIndexSizeGatherer
1146{
1147 GlobalIndexSizeGatherer(DataHandle& data_,
1148 std::vector<int>& ownedGlobalIndices_,
1149 std::vector<int>& ownedSizes_)
1150 : data(data_), ownedGlobalIndices(ownedGlobalIndices_), ownedSizes(ownedSizes_)
1151 {}
1152
1153 template<class T, class E>
1154 void operator()(T& i, E& entity)
1155 {
1156 ownedGlobalIndices.push_back(i);
1157 ownedSizes.push_back(data.size(entity));
1158 }
1159 DataHandle& data;
1160 std::vector<int>& ownedGlobalIndices;
1161 std::vector<int>& ownedSizes;
1162};
1163
1164template<class DataHandle>
1165struct DataGatherer
1166{
1167 DataGatherer(mover::MoveBuffer<typename DataHandle::DataType>& buffer_,
1168 DataHandle& data_)
1169 : buffer(buffer_), data(data_)
1170 {}
1171
1172 template<class T, class E>
1173 void operator()(T& /* it */, E& entity)
1174 {
1175 data.gather(buffer, entity);
1176 }
1177 mover::MoveBuffer<typename DataHandle::DataType>& buffer;
1178 DataHandle& data;
1179};
1180
1181}
1182
1183template<class DataHandle>
1184void CpGridData::gatherData(DataHandle& data, CpGridData* global_data,
1185 CpGridData* distributed_data)
1186{
1187#if HAVE_MPI
1188 if(data.contains(3,0))
1189 gatherCodimData<0>(data, global_data, distributed_data);
1190 if(data.contains(3,3))
1191 gatherCodimData<3>(data, global_data, distributed_data);
1192#endif
1193}
1194
1195template<int codim, class DataHandle>
1196void CpGridData::gatherCodimData(DataHandle& data, CpGridData* global_data,
1197 CpGridData* distributed_data)
1198{
1199#if HAVE_MPI
1200 // Get the mapping to global index from the global id set
1201 const std::vector<int>& mapping =
1202 distributed_data->global_id_set_->getMapping<codim>();
1203
1204 // Get the global indices and data size for the entities whose data is
1205 // to be sent, i.e. the ones that we own.
1206 std::vector<int> owned_global_indices;
1207 std::vector<int> owned_sizes;
1208 owned_global_indices.reserve(mapping.size());
1209 owned_sizes.reserve(mapping.size());
1210
1211 GlobalIndexSizeGatherer<DataHandle> gisg(data, owned_global_indices, owned_sizes);
1212 visitInterior<codim>(*distributed_data, mapping.begin(), mapping.end(), gisg);
1213
1214 // communicate the number of indices that each processor sends
1215 int no_indices=owned_sizes.size();
1216 // We will take the address of the first elemet for MPI_Allgather below.
1217 // Make sure the containers have such an element.
1218 if ( owned_global_indices.empty() )
1219 owned_global_indices.resize(1);
1220 if ( owned_sizes.empty() )
1221 owned_sizes.resize(1);
1222 std::vector<int> no_indices_to_recv(distributed_data->ccobj_.size());
1223 distributed_data->ccobj_.allgather(&no_indices, 1, &(no_indices_to_recv[0]));
1224 // compute size of the vector capable for receiving all indices
1225 // and allgather the global indices and the sizes.
1226 // calculate displacements
1227 std::vector<int> displ(distributed_data->ccobj_.size()+1, 0);
1228 std::transform(displ.begin(), displ.end()-1, no_indices_to_recv.begin(), displ.begin()+1,
1229 std::plus<int>());
1230 int global_size=displ[displ.size()-1];//+no_indices_to_recv[displ.size()-1];
1231 std::vector<int> global_indices(global_size);
1232 std::vector<int> global_sizes(global_size);
1233 MPI_Allgatherv(&(owned_global_indices[0]), no_indices, MPITraits<int>::getType(),
1234 &(global_indices[0]), &(no_indices_to_recv[0]), &(displ[0]),
1235 MPITraits<int>::getType(),
1236 distributed_data->ccobj_);
1237 MPI_Allgatherv(&(owned_sizes[0]), no_indices, MPITraits<int>::getType(),
1238 &(global_sizes[0]), &(no_indices_to_recv[0]), &(displ[0]),
1239 MPITraits<int>::getType(),
1240 distributed_data->ccobj_);
1241 std::vector<int>().swap(owned_global_indices); // free data for reuse.
1242 // Compute the number of data items to send
1243 std::vector<int> no_data_send(distributed_data->ccobj_.size());
1244 for(typename std::vector<int>::iterator begin=no_data_send.begin(),
1245 i=begin, end=no_data_send.end(); i!=end; ++i)
1246 *i = std::accumulate(global_sizes.begin()+displ[i-begin],
1247 global_sizes.begin()+displ[i-begin+1], std::size_t());
1248 // free at least some memory that can be reused.
1249 std::vector<int>().swap(owned_sizes);
1250 // compute the displacements for receiving with allgatherv
1251 displ[0]=0;
1252 std::transform(displ.begin(), displ.end()-1, no_data_send.begin(), displ.begin()+1,
1253 std::plus<std::size_t>());
1254 // Compute the number of data items we will receive
1255 int no_data_recv = displ[displ.size()-1];//+global_sizes[displ.size()-1];
1256
1257 // Collect the data to send, gather it
1258 mover::MoveBuffer<typename DataHandle::DataType> local_data_buffer, global_data_buffer;
1259 if ( no_data_send[distributed_data->ccobj_.rank()] )
1260 {
1261 local_data_buffer.resize(no_data_send[distributed_data->ccobj_.rank()]);
1262 }
1263 else
1264 {
1265 local_data_buffer.resize(1);
1266 }
1267 global_data_buffer.resize(no_data_recv);
1268
1269 DataGatherer<DataHandle> gatherer(local_data_buffer, data);
1270 visitInterior<codim>(*distributed_data, mapping.begin(), mapping.end(), gatherer);
1271 MPI_Allgatherv(&(local_data_buffer.buffer_[0]), no_data_send[distributed_data->ccobj_.rank()],
1272 MPITraits<typename DataHandle::DataType>::getType(),
1273 &(global_data_buffer.buffer_[0]), &(no_data_send[0]), &(displ[0]),
1274 MPITraits<typename DataHandle::DataType>::getType(),
1275 distributed_data->ccobj_);
1276 Entity2IndexDataHandle<DataHandle, codim> edata(*global_data, data);
1277 int offset=0;
1278 for(int i=0; i< codim; ++i)
1279 offset+=global_data->size(i);
1280
1281 typename std::vector<int>::const_iterator s=global_sizes.begin();
1282 for(typename std::vector<int>::const_iterator i=global_indices.begin(),
1283 end=global_indices.end();
1284 i!=end; ++s, ++i)
1285 {
1286 edata.scatter(global_data_buffer, *i-offset, *s);
1287 }
1288#endif
1289}
1290
1291} // end namespace cpgrid
1292} // end namespace Dune
1293
1294#endif
1295
1296#endif
DataHandle & data
Definition: CpGridData.hpp:1159
mover::MoveBuffer< typename DataHandle::DataType > & buffer
Definition: CpGridData.hpp:1177
std::vector< int > & ownedGlobalIndices
Definition: CpGridData.hpp:1160
void refine_and_check(const Dune::cpgrid::Geometry< 3, 3 > &, const std::array< int, 3 > &, bool)
std::vector< int > & ownedSizes
Definition: CpGridData.hpp:1161
[ provides Dune::Grid ]
Definition: CpGrid.hpp:203
Struct that hods all the data needed to represent a Cpgrid.
Definition: CpGridData.hpp:116
auto faceToPoint(int faceIdx) const
Definition: CpGridData.hpp:356
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:575
CpGridDataTraits::CommunicationType CommunicationType
type of OwnerOverlap communication for cells
Definition: CpGridData.hpp:625
@ MAX_DATA_PER_CELL
The maximum data items allowed per cell (DUNE < 2.5.2)
Definition: CpGridData.hpp:141
CpGridDataTraits::ParallelIndexSet ParallelIndexSet
The type of the parallel index set.
Definition: CpGridData.hpp:628
int size(GeometryType type) const
number of leaf entities per geometry type in this process
Definition: CpGridData.hpp:173
const std::array< int, 3 > & logicalCartesianSize() const
Definition: CpGridData.hpp:583
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:937
auto faceTag(int faceIdx) const
Definition: CpGridData.hpp:344
bool uniqueBoundaryIds() const
Definition: CpGridData.hpp:538
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:468
std::array< double, 3 > computeEclCentroid(const Entity< 0 > &elem) const
void computeCommunicationInterfaces(int noexistingPoints)
int getLeafIdxFromLevelIdx(int level_cell_idx) const
Definition: CpGridData.hpp:481
const auto & getCornerHistory(int cornerIdx) const
Definition: CpGridData.hpp:371
RemoteIndices & cellRemoteIndices()
Definition: CpGridData.hpp:659
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:613
const std::vector< int > & globalCell() const
Definition: CpGridData.hpp:388
CpGridDataTraits::InterfaceMap InterfaceMap
The type of the map describing communication interfaces.
Definition: CpGridData.hpp:622
CpGridDataTraits::Communication Communication
The type of the collective communication.
Definition: CpGridData.hpp:612
int numFaces() const
Definition: CpGridData.hpp:361
const std::vector< std::tuple< int, std::vector< int > > > & getParentToChildren() const
Definition: CpGridData.hpp:472
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:563
CommunicationType & cellCommunication()
Get the owner-overlap-copy communication for cells.
Definition: CpGridData.hpp:636
auto cellToFace(int cellIdx) const
Definition: CpGridData.hpp:324
auto faceNormals(int faceIdx) const
Definition: CpGridData.hpp:350
CpGridDataTraits::RemoteIndices RemoteIndices
The type of the remote indices information.
Definition: CpGridData.hpp:631
auto cornerHistorySize() const
Definition: CpGridData.hpp:366
ParallelIndexSet & cellIndexSet()
Definition: CpGridData.hpp:649
const auto & cellToPoint(int cellIdx) const
Definition: CpGridData.hpp:334
int getMark(const cpgrid::Entity< 0 > &element) const
Return refinement mark for entity.
const ParallelIndexSet & cellIndexSet() const
Definition: CpGridData.hpp:654
CpGridDataTraits::MPICommunicator MPICommunicator
The type of the mpi communicator.
Definition: CpGridData.hpp:610
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:453
const auto & cellToPoint() const
Definition: CpGridData.hpp:329
const std::vector< double > & zcornData() const
Definition: CpGridData.hpp:556
void setUniqueBoundaryIds(bool uids)
Definition: CpGridData.hpp:545
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:439
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:644
int cellFace(int cell, int local_index) const
Definition: CpGridData.hpp:319
const cpgrid::IdSet & localIdSet() const
Get the local index set.
Definition: CpGridData.hpp:569
const cpgrid::DefaultGeometryPolicy getGeometry() const
Definition: CpGridData.hpp:476
bool adapt()
TO DO: Documentation. Triggers the grid refinement process - Currently, returns preAdapt()
int faceToCellSize(int face) const
Definition: CpGridData.hpp:339
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:619
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:671
const RemoteIndices & cellRemoteIndices() const
Definition: CpGridData.hpp:664
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:971
void write(const T &data)
Definition: CpGridData.hpp:978
void reset()
Definition: CpGridData.hpp:982
void read(T &data)
Definition: CpGridData.hpp:974
void resize(std::size_t size)
Definition: CpGridData.hpp:986
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
Definition: CpGridData.hpp:1002
BaseMover(DataHandle &data)
Definition: CpGridData.hpp:1003
void moveData(const E &from, const E &to)
Definition: CpGridData.hpp:1007
MoveBuffer< typename DataHandle::DataType > buffer
Definition: CpGridData.hpp:1016
DataHandle & data_
Definition: CpGridData.hpp:1015
Definition: CpGridData.hpp:1022
void operator()(std::size_t from_cell_index, std::size_t to_cell_index)
Definition: CpGridData.hpp:1028
CpGridData * scatterView_
Definition: CpGridData.hpp:1035
CpGridData * gatherView_
Definition: CpGridData.hpp:1034
Mover(DataHandle &data, CpGridData *gatherView, CpGridData *scatterView)
Definition: CpGridData.hpp:1023
Definition: CpGridData.hpp:1040
Mover(DataHandle &data, CpGridData *gatherView, CpGridData *scatterView)
Definition: CpGridData.hpp:1041
CpGridData * gatherView_
Definition: CpGridData.hpp:1058
CpGridData * scatterView_
Definition: CpGridData.hpp:1059
void operator()(std::size_t from_cell_index, std::size_t to_cell_index)
Definition: CpGridData.hpp:1046
Definition: CpGridData.hpp:1064
CpGridData * scatterView_
Definition: CpGridData.hpp:1082
CpGridData * gatherView_
Definition: CpGridData.hpp:1081
Mover(DataHandle &data, CpGridData *gatherView, CpGridData *scatterView)
Definition: CpGridData.hpp:1065
void operator()(std::size_t from_cell_index, std::size_t to_cell_index)
Definition: CpGridData.hpp:1069
Definition: CpGridData.hpp:997
Definition: preprocess.h:56