My Project
Loading...
Searching...
No Matches
PropsCentroidsDataHandle.hpp
1/*
2 Copyright 2020 Equinor AS.
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
26#ifndef PROPS_CENTROIDS_DATAHANDLE_HPP
27#define PROPS_CENTROIDS_DATAHANDLE_HPP
28
29#if HAVE_MPI
30
31#include <opm/input/eclipse/EclipseState/Grid/FieldData.hpp>
32
33#include <opm/simulators/utils/ParallelEclipseState.hpp>
34#include <opm/simulators/utils/ParallelRestart.hpp>
35#include <dune/grid/common/datahandleif.hh>
36#include <dune/grid/common/mcmgmapper.hh>
37#include <dune/grid/common/partitionset.hh>
38#include <dune/common/parallel/mpihelper.hh>
39#include <unordered_map>
40#include <iostream>
41
42namespace Opm
43{
44
50template<class Grid>
51class PropsCentroidsDataHandle
52 : public Dune::CommDataHandleIF< PropsCentroidsDataHandle<Grid>, double>
53{
54public:
56 using DataType = std::pair<double, unsigned char>;
57
67 PropsCentroidsDataHandle(const Grid& grid, ParallelEclipseState& eclState,
68 const EclipseGrid* eclGridOnRoot,
69 std::vector<double>& centroids,
70 const typename Dune::CartesianIndexMapper<Grid>& cartMapper)
71 : m_grid(grid),
72 m_distributed_fieldProps(eclState.m_fieldProps),
73 m_centroids(centroids)
74 {
75 // Scatter the keys
76 const Parallel::Communication comm = m_grid.comm();
77 if (comm.rank() == 0)
78 {
79 const FieldPropsManager& globalProps = eclState.globalFieldProps();
80 m_intKeys = globalProps.keys<int>();
81 m_doubleKeys = globalProps.keys<double>();
82 m_distributed_fieldProps.copyTran(globalProps);
83 }
84
85 EclMpiSerializer ser(comm);
86 ser.broadcast(*this);
87
88 m_no_data = m_intKeys.size() + m_doubleKeys.size() + Grid::dimensionworld;
89
90 if (comm.rank() == 0) {
91 const FieldPropsManager& globalProps = eclState.globalFieldProps();
92 const auto& idSet = m_grid.localIdSet();
93 const auto& gridView = m_grid.levelGridView(0);
94 using ElementMapper =
95 Dune::MultipleCodimMultipleGeomTypeMapper<typename Grid::LevelGridView>;
96 ElementMapper elemMapper(gridView, Dune::mcmgElementLayout());
97
98 for (const auto &element : elements(gridView, Dune::Partitions::interiorBorder))
99 {
100 const auto& id = idSet.id(element);
101 auto index = elemMapper.index(element);
102 auto& data = elementData_[id];
103 data.reserve(m_no_data);
104
105 for (const auto& intKey : m_intKeys)
106 {
107 const auto& fieldData = globalProps.get_int_field_data(intKey);
108 data.emplace_back(fieldData.data[index],
109 static_cast<unsigned char>(fieldData.value_status[index]));
110 }
111
112 for (const auto& doubleKey : m_doubleKeys)
113 {
114 // We need to allow unsupported keywords to get the data
115 // for TranCalculator, too.
116 const auto& fieldData = globalProps.get_double_field_data(doubleKey,
117 /* allow_unsupported = */ true);
118 data.emplace_back(fieldData.data[index],
119 static_cast<unsigned char>(fieldData.value_status[index]));
120 }
121
122 auto cartIndex = cartMapper.cartesianIndex(index);
123 const auto& center = eclGridOnRoot->getCellCenter(cartIndex);
124 for (int dim = 0; dim < Grid::dimensionworld; ++dim)
125 data.emplace_back(center[dim], '1'); // write garbage for value_status
126 }
127 }
128 }
129
130 ~PropsCentroidsDataHandle()
131 {
132 // distributed grid is now correctly set up.
133 for (const auto& intKey : m_intKeys)
134 {
135 m_distributed_fieldProps.m_intProps[intKey].data.resize(m_grid.size(0));
136 m_distributed_fieldProps.m_intProps[intKey].value_status.resize(m_grid.size(0));
137 }
138
139 for (const auto& doubleKey : m_doubleKeys)
140 {
141 m_distributed_fieldProps.m_doubleProps[doubleKey].data.resize(m_grid.size(0));
142 m_distributed_fieldProps.m_doubleProps[doubleKey].value_status.resize(m_grid.size(0));
143 }
144
145 m_centroids.resize(m_grid.size(0) * Grid::dimensionworld);
146
147 // copy data for the persistent mao to the field properties
148 const auto& idSet = m_grid.localIdSet();
149 const auto& gridView = m_grid.levelGridView(0);
150 using ElementMapper =
151 Dune::MultipleCodimMultipleGeomTypeMapper<typename Grid::LevelGridView>;
152 ElementMapper elemMapper(gridView, Dune::mcmgElementLayout());
153
154 for (const auto &element : elements( gridView, Dune::Partitions::all))
155 {
156 std::size_t counter{};
157 const auto& id = idSet.id(element);
158 auto index = elemMapper.index(element);
159 auto data = elementData_.find(id);
160 assert(data != elementData_.end());
161
162 for (const auto& intKey : m_intKeys)
163 {
164 const auto& pair = data->second[counter++];
165 m_distributed_fieldProps.m_intProps[intKey].data[index] = static_cast<int>(pair.first);
166 m_distributed_fieldProps.m_intProps[intKey].value_status[index] = static_cast<value::status>(pair.second);
167 }
168
169 for (const auto& doubleKey : m_doubleKeys)
170 {
171 const auto& pair = data->second[counter++];
172 m_distributed_fieldProps.m_doubleProps[doubleKey].data[index] = pair.first;
173 m_distributed_fieldProps.m_doubleProps[doubleKey].value_status[index] = static_cast<value::status>(pair.second);
174 }
175
176 auto centroidIter = m_centroids.begin() + Grid::dimensionworld * index;
177 auto centroidIterEnd = centroidIter + Grid::dimensionworld;
178 for ( ; centroidIter != centroidIterEnd; ++centroidIter )
179 *centroidIter = data->second[counter++].first; // value_status discarded
180 }
181 }
182
183 bool contains(int /* dim */, int codim)
184 {
185 return codim == 0;
186 }
187
188 bool fixedsize(int /* dim */, int /* codim */)
189 {
190 return true;
191 }
192 bool fixedSize(int /* dim */, int /* codim */)
193 {
194 return true;
195 }
196
197 template<class EntityType>
198 std::size_t size(const EntityType /* entity */)
199 {
200 return m_no_data;
201 }
202
203 template<class BufferType, class EntityType>
204 void gather(BufferType& buffer, const EntityType& e) const
205 {
206 auto iter = elementData_.find(m_grid.localIdSet().id(e));
207 assert(iter != elementData_.end());
208 for (const auto& data : iter->second)
209 {
210 buffer.write(data);
211 }
212 }
213
214 template<class BufferType, class EntityType>
215 void scatter(BufferType& buffer, const EntityType& e, std::size_t n)
216 {
217 assert(n == m_no_data);
218 auto& array = elementData_[m_grid.localIdSet().id(e)];
219 array.resize(n);
220 for (auto& data : array)
221 {
222 buffer.read(data);
223 }
224 }
225
226 template<class Serializer>
227 void serializeOp(Serializer& serializer)
228 {
229 serializer(m_intKeys);
230 serializer(m_doubleKeys);
231 m_distributed_fieldProps.serializeOp(serializer);
232 }
233
234private:
235 using LocalIdSet = typename Grid::LocalIdSet;
236 const Grid& m_grid;
238 ParallelFieldPropsManager& m_distributed_fieldProps;
240 std::vector<std::string> m_intKeys;
242 std::vector<std::string> m_doubleKeys;
246 std::unordered_map<typename LocalIdSet::IdType, std::vector<std::pair<double,unsigned char> > > elementData_;
248 std::vector<double>& m_centroids;
250 std::size_t m_no_data;
251};
252
253} // end namespace Opm
254#endif // HAVE_MPI
255#endif // PROPS_CENTROIDS_DATAHANDLE_HPP
256
Definition findOverlapRowsAndColumns.hpp:29
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition BlackoilPhases.hpp:27