27#ifndef PROPS_DATAHANDLE_HPP
28#define PROPS_DATAHANDLE_HPP
32#include <opm/input/eclipse/EclipseState/Grid/FieldData.hpp>
37#include <dune/grid/common/datahandleif.hh>
38#include <dune/grid/common/mcmgmapper.hh>
39#include <dune/grid/common/partitionset.hh>
40#include <dune/common/parallel/mpihelper.hh>
44#include <unordered_map>
57 :
public Dune::CommDataHandleIF< PropsDataHandle<Grid>, double>
61 using DataType = std::pair<double, unsigned char>;
69 m_distributed_fieldProps(eclState.m_fieldProps)
76 m_intKeys = globalProps.keys<
int>();
77 m_doubleKeys = globalProps.keys<
double>();
78 m_distributed_fieldProps.
copyTran(globalProps);
82 m_doubleMult.reserve(m_doubleKeys.size());
83 for (
const auto& doubleKey : m_doubleKeys)
85 const auto& fieldData = globalProps.get_double_field_data(doubleKey,
87 m_doubleMult.push_back(fieldData.numValuePerCell());
94 int hasMultiValuedIntField = 0;
95 if (comm.rank() == 0) {
97 hasMultiValuedIntField = std::any_of(
98 m_intKeys.begin(), m_intKeys.end(),
99 [&globalProps](
const std::string& key) {
100 return globalProps.get_int_field_data(key).numValuePerCell() > 1;
103 comm.broadcast(&hasMultiValuedIntField, 1, 0);
104 if (hasMultiValuedIntField) {
105 throw std::runtime_error {
106 "Distributing multi-valued integer field properties is not supported"
110 int hasLgr = (comm.rank() == 0) && (eclState.getLgrs().size() > 0);
111 comm.broadcast(&hasLgr, 1, 0);
112 const bool hasMultiValuedField =
113 std::any_of(m_doubleMult.begin(), m_doubleMult.end(),
114 [](
const std::size_t multiplicity) { return multiplicity > 1; });
115 if (hasLgr && hasMultiValuedField) {
116 throw std::runtime_error {
117 "Distributing multi-valued field properties with LGRs is not supported"
121 m_no_data = m_intKeys.size() +
122 std::accumulate(m_doubleMult.begin(), m_doubleMult.end(), std::size_t{0});
124 if (comm.rank() == 0) {
126 const auto& idSet = m_grid.localIdSet();
127 const auto& gridView = m_grid.levelGridView(0);
128 using ElementMapper =
129 Dune::MultipleCodimMultipleGeomTypeMapper<typename Grid::LevelGridView>;
130 ElementMapper elemMapper(gridView, Dune::mcmgElementLayout());
131 const std::size_t numCells = gridView.size(0);
133 for (
const auto &element : elements(gridView, Dune::Partitions::interiorBorder))
135 const auto&
id = idSet.id(element);
136 auto index = elemMapper.index(element);
137 auto& data = elementData_[id];
138 data.reserve(m_no_data);
140 for (
const auto& intKey : m_intKeys)
142 const auto& fieldData = globalProps.get_int_field_data(intKey);
143 data.emplace_back(fieldData.data[index],
144 static_cast<unsigned char>(fieldData.value_status[index]));
147 for (std::size_t keyIdx = 0; keyIdx < m_doubleKeys.size(); ++keyIdx)
151 const auto& fieldData = globalProps.get_double_field_data(m_doubleKeys[keyIdx],
153 for (std::size_t comp = 0; comp < m_doubleMult[keyIdx]; ++comp)
155 const auto dataIdx = comp * numCells + index;
156 data.emplace_back(fieldData.data[dataIdx],
157 static_cast<unsigned char>(fieldData.value_status[dataIdx]));
167 const auto& gridView = m_grid.levelGridView(0);
168 const std::size_t numCells = gridView.size(0);
169 for (
const auto& intKey : m_intKeys)
171 m_distributed_fieldProps.
m_intProps[intKey].data.resize(numCells);
172 m_distributed_fieldProps.
m_intProps[intKey].value_status.resize(numCells);
175 for (std::size_t keyIdx = 0; keyIdx < m_doubleKeys.size(); ++keyIdx)
177 auto& props = m_distributed_fieldProps.
m_doubleProps[m_doubleKeys[keyIdx]];
178 props.data.resize(m_doubleMult[keyIdx] * numCells);
179 props.value_status.resize(m_doubleMult[keyIdx] * numCells);
181 props.kw_info.num_value_per_cell(m_doubleMult[keyIdx]);
185 const auto& idSet = m_grid.localIdSet();
186 using ElementMapper =
187 Dune::MultipleCodimMultipleGeomTypeMapper<typename Grid::LevelGridView>;
188 ElementMapper elemMapper(gridView, Dune::mcmgElementLayout());
190 for (
const auto &element : elements( gridView, Dune::Partitions::all))
192 std::size_t counter{};
193 const auto&
id = idSet.id(element);
194 auto index = elemMapper.index(element);
195 auto data = elementData_.find(
id);
196 assert(data != elementData_.end());
198 for (
const auto& intKey : m_intKeys)
200 const auto& pair = data->second[counter++];
201 m_distributed_fieldProps.
m_intProps[intKey].data[index] =
static_cast<int>(pair.first);
202 m_distributed_fieldProps.
m_intProps[intKey].value_status[index] =
static_cast<value::status
>(pair.second);
205 for (std::size_t keyIdx = 0; keyIdx < m_doubleKeys.size(); ++keyIdx)
207 auto& props = m_distributed_fieldProps.
m_doubleProps[m_doubleKeys[keyIdx]];
208 for (std::size_t comp = 0; comp < m_doubleMult[keyIdx]; ++comp)
210 const auto& pair = data->second[counter++];
211 props.data[comp * numCells + index] = pair.first;
212 props.value_status[comp * numCells + index] =
static_cast<value::status
>(pair.second);
232 template<
class EntityType>
233 std::size_t
size(
const EntityType )
238 template<
class BufferType,
class EntityType>
239 void gather(BufferType& buffer,
const EntityType& e)
const
241 auto iter = elementData_.find(m_grid.localIdSet().id(e));
242 assert(iter != elementData_.end());
243 for (
const auto& data : iter->second)
249 template<
class BufferType,
class EntityType>
250 void scatter(BufferType& buffer,
const EntityType& e, std::size_t n)
252 assert(n == m_no_data);
253 auto& array = elementData_[m_grid.localIdSet().id(e)];
255 for (
auto& data : array)
261 template<
class Serializer>
264 serializer(m_intKeys);
265 serializer(m_doubleKeys);
266 serializer(m_doubleMult);
271 using LocalIdSet =
typename Grid::LocalIdSet;
276 std::vector<std::string> m_intKeys;
278 std::vector<std::string> m_doubleKeys;
280 std::vector<std::size_t> m_doubleMult;
284 std::unordered_map<typename LocalIdSet::IdType, std::vector<std::pair<double,unsigned char> > > elementData_;
286 std::size_t m_no_data;
Class for serializing and broadcasting data using MPI.
Definition: MPISerializer.hpp:38
void broadcast(RootRank rootrank, Args &&... args)
Definition: MPISerializer.hpp:47
Parallel frontend to the EclipseState.
Definition: ParallelEclipseState.hpp:153
const FieldPropsManager & globalFieldProps() const override
Returns a const ref to global field properties.
Parallel frontend to the field properties.
Definition: ParallelEclipseState.hpp:42
std::map< std::string, Fieldprops::FieldData< int > > m_intProps
Map of integer properties in process-local compressed indices.
Definition: ParallelEclipseState.hpp:132
void serializeOp(Serializer &serializer)
Definition: ParallelEclipseState.hpp:126
void copyTran(const FieldPropsManager &from)
Definition: ParallelEclipseState.hpp:120
std::map< std::string, Fieldprops::FieldData< double > > m_doubleProps
Map of double properties in process-local compressed indices.
Definition: ParallelEclipseState.hpp:133
A Data handle to communicate the field properties during load balance.
Definition: PropsDataHandle.hpp:58
PropsDataHandle(const Grid &grid, ParallelEclipseState &eclState)
Constructor.
Definition: PropsDataHandle.hpp:67
std::size_t size(const EntityType)
Definition: PropsDataHandle.hpp:233
std::pair< double, unsigned char > DataType
the data type we send (ints are converted to double)
Definition: PropsDataHandle.hpp:61
void serializeOp(Serializer &serializer)
Definition: PropsDataHandle.hpp:262
bool fixedSize(int, int)
Definition: PropsDataHandle.hpp:227
bool fixedsize(int, int)
Definition: PropsDataHandle.hpp:223
bool contains(int, int codim)
Definition: PropsDataHandle.hpp:218
~PropsDataHandle()
Definition: PropsDataHandle.hpp:164
void gather(BufferType &buffer, const EntityType &e) const
Definition: PropsDataHandle.hpp:239
void scatter(BufferType &buffer, const EntityType &e, std::size_t n)
Definition: PropsDataHandle.hpp:250
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Definition: blackoilbioeffectsmodules.hh:45
Avoid mistakes in calls to broadcast() by wrapping the root argument in an explicit type.
Definition: MPISerializer.hpp:33