20#ifndef OPM_RESERVOIR_COUPLING_MPI_TRAITS_HPP
21#define OPM_RESERVOIR_COUPLING_MPI_TRAITS_HPP
23#include <dune/common/parallel/mpitraits.hh>
85template<
class Struct,
auto... Members>
94 std::call_once(flag_, [] {
96 constexpr std::size_t N =
sizeof...(Members);
103 std::array<int, N> blk{}; blk.fill(1);
105 std::array<MPI_Aint, N> disp{};
107 std::array<MPI_Datatype, N> types{};
113 MPI_Get_address(&dummy, &base);
117 ( processMember<Members>(dummy, base, disp, blk, types, i++), ... );
126 for (std::size_t k = 1; k < N; ++k)
127 assert(disp[k-1] < disp[k] &&
"StructMPITraits member list not in declaration order");
128 MPI_Type_create_struct(N, blk.data(), disp.data(), types.data(), &tmp);
130 MPI_Type_create_resized(tmp, 0,
sizeof(Struct), &type_);
131 MPI_Type_commit(&type_);
144 template<
class T>
struct is_std_array : std::false_type {};
145 template<
class T, std::
size_t N>
146 struct is_std_array<std::array<T, N>> : std::true_type {};
148 template <
typename T,
typename Enable =
void>
150 using Type = MPITraits<T>;
153 template <
typename T>
154 struct MpiDispatch<T, typename std::enable_if<std::is_enum<T>::value>::type> {
155 using Type = MPITraits<typename std::underlying_type<T>::type>;
158 template<auto Member,
class Dummy>
159 static void processMember(Dummy& d, MPI_Aint base,
160 std::array<MPI_Aint,
sizeof...(Members)>& disp,
161 std::array<
int,
sizeof...(Members)>& blk,
162 std::array<MPI_Datatype,
sizeof...(Members)>& types,
165 using MemberT = std::remove_reference_t<
decltype(d.*Member)>;
167 MPI_Get_address(&(d.*Member), &disp[idx]);
170 if constexpr (std::is_array_v<MemberT>) {
172 using Elem = std::remove_extent_t<MemberT>;
173 blk [idx] = std::extent_v<MemberT>;
176 else if constexpr (is_std_array<MemberT>::value) {
178 using Elem =
typename MemberT::value_type;
179 blk [idx] = std::tuple_size<MemberT>::value;
185 using MPIType =
typename MpiDispatch<MemberT>::Type;
192 static inline MPI_Datatype type_ = MPI_DATATYPE_NULL;
193 static inline std::once_flag flag_;
197template<
class Struct,
auto... Members>
209template<
class Scalar>
213 ::Opm::ReservoirCoupling::InjectionGroupTarget<Scalar>,
214 &::Opm::ReservoirCoupling::InjectionGroupTarget<Scalar>::group_name_idx,
215 &::Opm::ReservoirCoupling::InjectionGroupTarget<Scalar>::target,
216 &::Opm::ReservoirCoupling::InjectionGroupTarget<Scalar>::cmode,
217 &::Opm::ReservoirCoupling::InjectionGroupTarget<Scalar>::phase> { };
220template<
class Scalar>
224 ::Opm::ReservoirCoupling::ProductionGroupTarget<Scalar>,
225 &::Opm::ReservoirCoupling::ProductionGroupTarget<Scalar>::group_name_idx,
226 &::Opm::ReservoirCoupling::ProductionGroupTarget<Scalar>::target,
227 &::Opm::ReservoirCoupling::ProductionGroupTarget<Scalar>::cmode> { };
242template<
class Scalar>
245 ::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>,
246 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::potentials,
247 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::surface_rates,
248 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::reservoir_rates,
249 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::voidage_rate,
250 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::gas_reinjection_rate
266template<
class Scalar>
269 ::Opm::ReservoirCoupling::SlaveGroupInjectionData<Scalar>,
270 &::Opm::ReservoirCoupling::SlaveGroupInjectionData<Scalar>::surface_rates,
271 &::Opm::ReservoirCoupling::SlaveGroupInjectionData<Scalar>::reservoir_rates
Definition: fvbaseprimaryvariables.hh:161
TYPE getType(const TABLE &table)
Generic MPI traits implementation for structs.
Definition: ReservoirCouplingMpiTraits.hpp:87
static constexpr bool is_intrinsic
Definition: ReservoirCouplingMpiTraits.hpp:140
static MPI_Datatype getType()
Definition: ReservoirCouplingMpiTraits.hpp:88
Definition: ReservoirCoupling.hpp:211
Definition: ReservoirCoupling.hpp:221
Definition: ReservoirCoupling.hpp:205
Definition: ReservoirCoupling.hpp:190