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