20#ifndef OPM_RESERVOIR_COUPLING_MPI_TRAITS_HPP
21#define OPM_RESERVOIR_COUPLING_MPI_TRAITS_HPP
23#include <dune/common/parallel/mpitraits.hh>
84template<
class Struct,
auto... Members>
93 std::call_once(flag_, [] {
95 constexpr std::size_t N =
sizeof...(Members);
102 std::array<int, N> blk{}; blk.fill(1);
104 std::array<MPI_Aint, N> disp{};
106 std::array<MPI_Datatype, N> types{};
112 MPI_Get_address(&dummy, &base);
116 ( processMember<Members>(dummy, base, disp, blk, types, i++), ... );
120 MPI_Type_create_struct(N, blk.data(), disp.data(), types.data(), &tmp);
122 MPI_Type_create_resized(tmp, 0,
sizeof(Struct), &type_);
123 MPI_Type_commit(&type_);
136 template<
class T>
struct is_std_array : std::false_type {};
137 template<
class T, std::
size_t N>
138 struct is_std_array<std::array<T, N>> : std::true_type {};
140 template <
typename T,
typename Enable =
void>
142 using Type = MPITraits<T>;
145 template <
typename T>
146 struct MpiDispatch<T, typename std::enable_if<std::is_enum<T>::value>::type> {
147 using Type = MPITraits<typename std::underlying_type<T>::type>;
150 template<auto Member,
class Dummy>
151 static void processMember(Dummy& d, MPI_Aint base,
152 std::array<MPI_Aint,
sizeof...(Members)>& disp,
153 std::array<
int,
sizeof...(Members)>& blk,
154 std::array<MPI_Datatype,
sizeof...(Members)>& types,
157 using MemberT = std::remove_reference_t<
decltype(d.*Member)>;
159 MPI_Get_address(&(d.*Member), &disp[idx]);
162 if constexpr (std::is_array_v<MemberT>) {
164 using Elem = std::remove_extent_t<MemberT>;
165 blk [idx] = std::extent_v<MemberT>;
168 else if constexpr (is_std_array<MemberT>::value) {
170 using Elem =
typename MemberT::value_type;
171 blk [idx] = std::tuple_size<MemberT>::value;
177 using MPIType =
typename MpiDispatch<MemberT>::Type;
184 static inline MPI_Datatype type_ = MPI_DATATYPE_NULL;
185 static inline std::once_flag flag_;
189template<
class Struct,
auto... Members>
207template<
class Scalar>
210 ::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>,
211 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::potentials,
212 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::surface_rates,
213 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::voidage_rate,
214 &::Opm::ReservoirCoupling::SlaveGroupProductionData<Scalar>::gas_reinjection_rate
230template<
class Scalar>
233 ::Opm::ReservoirCoupling::SlaveGroupInjectionData<Scalar>,
234 &::Opm::ReservoirCoupling::SlaveGroupInjectionData<Scalar>::surface_rates,
235 &::Opm::ReservoirCoupling::SlaveGroupInjectionData<Scalar>::reservoir_rates
Definition: fvbaseprimaryvariables.hh:161
TYPE getType(const TABLE &table)
Generic MPI traits implementation for structs.
Definition: ReservoirCouplingMpiTraits.hpp:86
static constexpr bool is_intrinsic
Definition: ReservoirCouplingMpiTraits.hpp:132
static MPI_Datatype getType()
Definition: ReservoirCouplingMpiTraits.hpp:87
Definition: ReservoirCoupling.hpp:198
Definition: ReservoirCoupling.hpp:184