opm-simulators
PropsDataHandle.hpp
1 /*
2  Copyright 2020, 2023 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_DATAHANDLE_HPP
27 #define PROPS_DATAHANDLE_HPP
28 
29 #if HAVE_MPI
30 
31 #include <opm/input/eclipse/EclipseState/Grid/FieldData.hpp>
32 
33 #include <opm/simulators/utils/MPISerializer.hpp>
34 #include <opm/simulators/utils/ParallelEclipseState.hpp>
35 #include <opm/simulators/utils/ParallelRestart.hpp>
36 #include <dune/grid/common/datahandleif.hh>
37 #include <dune/grid/common/mcmgmapper.hh>
38 #include <dune/grid/common/partitionset.hh>
39 #include <dune/common/parallel/mpihelper.hh>
40 #include <unordered_map>
41 #include <iostream>
42 
43 namespace Opm
44 {
45 
51 template<class Grid>
52 class PropsDataHandle
53  : public Dune::CommDataHandleIF< PropsDataHandle<Grid>, double>
54 {
55 public:
57  using DataType = std::pair<double, unsigned char>;
58 
63  PropsDataHandle(const Grid& grid, ParallelEclipseState& eclState)
64  : m_grid(grid),
65  m_distributed_fieldProps(eclState.m_fieldProps)
66  {
67  // Scatter the keys
68  const Parallel::Communication comm = m_grid.comm();
69  if (comm.rank() == 0)
70  {
71  const FieldPropsManager& globalProps = eclState.globalFieldProps();
72  m_intKeys = globalProps.keys<int>();
73  m_doubleKeys = globalProps.keys<double>();
74  m_distributed_fieldProps.copyTran(globalProps);
75  }
76 
77  Parallel::MpiSerializer ser(comm);
78  ser.broadcast(Parallel::RootRank{0}, *this);
79 
80  m_no_data = m_intKeys.size() + m_doubleKeys.size();
81 
82  if (comm.rank() == 0) {
83  const FieldPropsManager& globalProps = eclState.globalFieldProps();
84  const auto& idSet = m_grid.localIdSet();
85  const auto& gridView = m_grid.levelGridView(0);
86  using ElementMapper =
87  Dune::MultipleCodimMultipleGeomTypeMapper<typename Grid::LevelGridView>;
88  ElementMapper elemMapper(gridView, Dune::mcmgElementLayout());
89 
90  for (const auto &element : elements(gridView, Dune::Partitions::interiorBorder))
91  {
92  const auto& id = idSet.id(element);
93  auto index = elemMapper.index(element);
94  auto& data = elementData_[id];
95  data.reserve(m_no_data);
96 
97  for (const auto& intKey : m_intKeys)
98  {
99  const auto& fieldData = globalProps.get_int_field_data(intKey);
100  data.emplace_back(fieldData.data[index],
101  static_cast<unsigned char>(fieldData.value_status[index]));
102  }
103 
104  for (const auto& doubleKey : m_doubleKeys)
105  {
106  // We need to allow unsupported keywords to get the data
107  // for TranCalculator, too.
108  const auto& fieldData = globalProps.get_double_field_data(doubleKey,
109  /* allow_unsupported = */ true);
110  data.emplace_back(fieldData.data[index],
111  static_cast<unsigned char>(fieldData.value_status[index]));
112  }
113  }
114  }
115  }
116 
117  ~PropsDataHandle()
118  {
119  // distributed grid is now correctly set up.
120  for (const auto& intKey : m_intKeys)
121  {
122  m_distributed_fieldProps.m_intProps[intKey].data.resize(m_grid.size(0));
123  m_distributed_fieldProps.m_intProps[intKey].value_status.resize(m_grid.size(0));
124  }
125 
126  for (const auto& doubleKey : m_doubleKeys)
127  {
128  m_distributed_fieldProps.m_doubleProps[doubleKey].data.resize(m_grid.size(0));
129  m_distributed_fieldProps.m_doubleProps[doubleKey].value_status.resize(m_grid.size(0));
130  }
131 
132  // copy data for the persistent mao to the field properties
133  const auto& idSet = m_grid.localIdSet();
134  const auto& gridView = m_grid.levelGridView(0);
135  using ElementMapper =
136  Dune::MultipleCodimMultipleGeomTypeMapper<typename Grid::LevelGridView>;
137  ElementMapper elemMapper(gridView, Dune::mcmgElementLayout());
138 
139  for (const auto &element : elements( gridView, Dune::Partitions::all))
140  {
141  std::size_t counter{};
142  const auto& id = idSet.id(element);
143  auto index = elemMapper.index(element);
144  auto data = elementData_.find(id);
145  assert(data != elementData_.end());
146 
147  for (const auto& intKey : m_intKeys)
148  {
149  const auto& pair = data->second[counter++];
150  m_distributed_fieldProps.m_intProps[intKey].data[index] = static_cast<int>(pair.first);
151  m_distributed_fieldProps.m_intProps[intKey].value_status[index] = static_cast<value::status>(pair.second);
152  }
153 
154  for (const auto& doubleKey : m_doubleKeys)
155  {
156  const auto& pair = data->second[counter++];
157  m_distributed_fieldProps.m_doubleProps[doubleKey].data[index] = pair.first;
158  m_distributed_fieldProps.m_doubleProps[doubleKey].value_status[index] = static_cast<value::status>(pair.second);
159  }
160  }
161  }
162 
163  bool contains(int /* dim */, int codim)
164  {
165  return codim == 0;
166  }
167 
168  bool fixedsize(int /* dim */, int /* codim */)
169  {
170  return true;
171  }
172  bool fixedSize(int /* dim */, int /* codim */)
173  {
174  return true;
175  }
176 
177  template<class EntityType>
178  std::size_t size(const EntityType /* entity */)
179  {
180  return m_no_data;
181  }
182 
183  template<class BufferType, class EntityType>
184  void gather(BufferType& buffer, const EntityType& e) const
185  {
186  auto iter = elementData_.find(m_grid.localIdSet().id(e));
187  assert(iter != elementData_.end());
188  for (const auto& data : iter->second)
189  {
190  buffer.write(data);
191  }
192  }
193 
194  template<class BufferType, class EntityType>
195  void scatter(BufferType& buffer, const EntityType& e, std::size_t n)
196  {
197  assert(n == m_no_data);
198  auto& array = elementData_[m_grid.localIdSet().id(e)];
199  array.resize(n);
200  for (auto& data : array)
201  {
202  buffer.read(data);
203  }
204  }
205 
206  template<class Serializer>
207  void serializeOp(Serializer& serializer)
208  {
209  serializer(m_intKeys);
210  serializer(m_doubleKeys);
211  m_distributed_fieldProps.serializeOp(serializer);
212  }
213 
214 private:
215  using LocalIdSet = typename Grid::LocalIdSet;
216  const Grid& m_grid;
218  ParallelFieldPropsManager& m_distributed_fieldProps;
220  std::vector<std::string> m_intKeys;
222  std::vector<std::string> m_doubleKeys;
226  std::unordered_map<typename LocalIdSet::IdType, std::vector<std::pair<double,unsigned char> > > elementData_;
228  std::size_t m_no_data;
229 };
230 
231 } // end namespace Opm
232 
233 #endif // HAVE_MPI
234 #endif // PROPS_DATAHANDLE_HPP
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45