MultiComm.hpp
Go to the documentation of this file.
1/*
2 Copyright Equinor ASA 2026
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*/
19#ifndef OPM_MULTICOMM_HEADER_INCLUDED
20#define OPM_MULTICOMM_HEADER_INCLUDED
21
22#include <dune/common/parallel/communication.hh>
23#include <dune/common/hybridutilities.hh>
24
25#if HAVE_MPI
26#include <mpi.h>
27#include <dune/common/parallel/mpicommunication.hh>
28#endif
29
30#include <cmath>
31#include <cstddef>
32#include <tuple>
33#include <type_traits>
34
35namespace Dune
36{
37
39{
40public:
41 using size_type = std::size_t;
42
43 static constexpr size_type size()
44 {
45 return 0;
46 }
47 template <typename T>
48 void project(T& /*x*/) const
49 {
50 }
51 template <typename T1, typename T2>
52 void dot(const T1& x, const T1& y, T2& result) const
53 {
54 result = x.dot(y);
55 }
56 template <typename T>
57 double norm(const T& x) const
58 {
59 return x.two_norm();
60 }
61 template <typename T>
62 void copyOwnerToAll(const T& x, T& y) const
63 {
64 y = x;
65 }
66
67 auto communicator() const
68 {
69 return Dune::Communication<int>{};
70 }
71};
72
73#if HAVE_MPI
75{
76public:
77 using size_type = std::size_t;
78
80 : colcom_(MPI_COMM_WORLD)
81 {
82 }
83 static constexpr size_type size()
84 {
85 return 0;
86 }
87 template <typename T>
88 void project(T& /*x*/) const
89 {
90 }
91
92 template <typename T1, typename T2>
93 void dot(const T1& x, const T1& y, T2& result) const
94 {
95 result = x.dot(y);
96 result = colcom_.sum(result);
97 }
98
99 template <typename T>
100 double norm(const T& x) const
101 {
102 double result = x.dot(x);
103 result = colcom_.sum(result);
104 return std::sqrt(result);
105 }
106
107 template <typename T>
108 void copyOwnerToAll(const T& x, T& y) const
109 {
110 y = x;
111 }
112
113private:
114 Communication<MPI_Comm> colcom_;
115};
116#endif
117
118template <typename... Args>
119class MultiCommunicator : public std::tuple<Args...>
120{
121 using TupleType = std::tuple<Args...>;
122 using type = MultiCommunicator<Args...>;
123 using field_type = double;
124
125public:
126 using std::tuple<Args...>::tuple;
127 using size_type = std::size_t;
128
129 static constexpr size_type size()
130 {
131 return sizeof...(Args);
132 }
133
134 template <size_type index>
135 typename std::tuple_element<index, TupleType>::type&
136 operator[]([[maybe_unused]] const std::integral_constant<size_type, index> indexVariable)
137 {
138 return std::get<index>(*this);
139 }
140 template <size_type index>
141 const typename std::tuple_element<index, TupleType>::type&
142 operator[]([[maybe_unused]] const std::integral_constant<size_type, index> indexVariable) const
143 {
144 return std::get<index>(*this);
145 }
146
147 template <typename T>
148 void project(T& x) const
149 {
150 using namespace Dune::Hybrid;
151 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) { (*this)[i].project(x[i]); });
152 }
153 template <typename T1, typename T2>
154 void dot(const T1& x, const T1& y, T2& result) const
155 {
156 result = field_type(0);
157 using namespace Dune::Hybrid;
158 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
159 double result_tmp = 0;
160 (*this)[i].dot(x[i], y[i], result_tmp);
161 result += result_tmp;
162 });
163 }
164 template <typename T>
165 field_type norm(const T& x) const
166 {
167 field_type result(0);
168 using namespace Dune::Hybrid;
169 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
170 double result_tmp = 0.0;
171 (*this)[i].dot(x[i], x[i], result_tmp);
172 result += result_tmp;
173 });
174 return std::sqrt(result);
175 }
176 template <typename T>
177 void copyOwnerToAll(const T& x, T& y) const
178 {
179 using namespace Dune::Hybrid;
180 forEach(integralRange(Hybrid::size(*this)),
181 [&](auto&& i) { (*this)[i].copyOwnerToAll(x[i], y[i]); });
182 }
183
184 decltype(auto) communicator() const
185 {
186 return std::get<0>(*this).communicator();
187 }
188};
189
190} // namespace Dune
191
192#endif // OPM_MULTICOMM_HEADER_INCLUDED
Definition: MultiComm.hpp:75
void copyOwnerToAll(const T &x, T &y) const
Definition: MultiComm.hpp:108
double norm(const T &x) const
Definition: MultiComm.hpp:100
void project(T &) const
Definition: MultiComm.hpp:88
JacComm()
Definition: MultiComm.hpp:79
std::size_t size_type
Definition: MultiComm.hpp:77
void dot(const T1 &x, const T1 &y, T2 &result) const
Definition: MultiComm.hpp:93
static constexpr size_type size()
Definition: MultiComm.hpp:83
Definition: MultiComm.hpp:120
field_type norm(const T &x) const
Definition: MultiComm.hpp:165
void dot(const T1 &x, const T1 &y, T2 &result) const
Definition: MultiComm.hpp:154
std::tuple_element< index, TupleType >::type & operator[](const std::integral_constant< size_type, index > indexVariable)
Definition: MultiComm.hpp:136
std::size_t size_type
Definition: MultiComm.hpp:127
void copyOwnerToAll(const T &x, T &y) const
Definition: MultiComm.hpp:177
const std::tuple_element< index, TupleType >::type & operator[](const std::integral_constant< size_type, index > indexVariable) const
Definition: MultiComm.hpp:142
decltype(auto) communicator() const
Definition: MultiComm.hpp:184
static constexpr size_type size()
Definition: MultiComm.hpp:129
void project(T &x) const
Definition: MultiComm.hpp:148
Definition: MultiComm.hpp:39
double norm(const T &x) const
Definition: MultiComm.hpp:57
static constexpr size_type size()
Definition: MultiComm.hpp:43
std::size_t size_type
Definition: MultiComm.hpp:41
void copyOwnerToAll(const T &x, T &y) const
Definition: MultiComm.hpp:62
auto communicator() const
Definition: MultiComm.hpp:67
void dot(const T1 &x, const T1 &y, T2 &result) const
Definition: MultiComm.hpp:52
void project(T &) const
Definition: MultiComm.hpp:48
Definition: fvbaseprimaryvariables.hh:161