1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 /****************************************************************************/
4 /*                                                                          */
5 /* File:      reduct.c                                                      */
6 /*                                                                          */
7 /* Purpose:   standard parallel routines not supported by ddd               */
8 /*            reduction operations (GlobalSum, GlobalMax etc)               */
9 /*                                                                          */
10 /* Author:    Klaus Birken                                                  */
11 /*            Rechenzentrum Uni Stuttgart                                   */
12 /*            Universitaet Stuttgart                                        */
13 /*            Allmandring 30                                                */
14 /*            70550 Stuttgart                                               */
15 /*            internet: birken@rus.uni-stuttgart.de                         */
16 /*                                                                          */
17 /* History:   940128 kb  begin                                              */
18 /*            960902 kb  copied from fedemo, adapted                        */
19 /*                                                                          */
20 /* Remarks:                                                                 */
21 /*                                                                          */
22 /****************************************************************************/
23 
24 /****************************************************************************/
25 /*                                                                          */
26 /* include files                                                            */
27 /*            system include files                                          */
28 /*            application include files                                     */
29 /*                                                                          */
30 /****************************************************************************/
31 
32 /* standard C library */
33 #include <config.h>
34 #include <cstdlib>
35 #include <cstdio>
36 #include <cstddef>
37 
38 #include <type_traits>
39 
40 #ifdef ModelP
41 #  include <mpi.h>
42 #  include <dune/uggrid/parallel/ppif/ppifcontext.hh>
43 #endif
44 
45 #include <dune/uggrid/parallel/ppif/ppif.h>
46 #include <dune/uggrid/low/namespace.h>
47 #include <dune/uggrid/low/ugtypes.h>
48 #include <dune/uggrid/parallel/ddd/include/memmgr.h>
49 
50 #include <dune/uggrid/gm/pargm.h>
51 
52 
53 /* UG namespaces: */
54 USING_UG_NAMESPACES
55 
56 /* PPIF namespaces: */
57 using namespace PPIF;
58 
59 START_UGDIM_NAMESPACE
60 
61 /****************************************************************************/
62 /*                                                                          */
63 /* routines                                                                 */
64 /*                                                                          */
65 /****************************************************************************/
66 
67 
68 /* some useful functions by Peter Bastian, from ugp/ug/ugcom.c */
69 
70 #ifdef ModelP
71 
72 static_assert(
73   std::is_same<int, INT>::value,
74   "The implementation assumes that `int` and `INT` are the same type.");
75 static_assert(
76   std::is_same<double, DOUBLE>::value,
77   "The implementation assumes that `double` and `DOUBLE` are the same type.");
78 
79 /****************************************************************************/
80 /*D
81    UG_GlobalMaxINT - get maximum for INT value
82 
83    SYNOPSIS:
84    INT UG_GlobalMaxINT (INT i)
85 
86    PARAMETERS:
87    .  i - calculate maximum for this value
88 
89    DESCRIPTION:
90    This function calculates the maximum of i over all processors.
91 
92    RETURN VALUE:
93    The maximum value of i over all processors.
94 
95    D*/
96 /****************************************************************************/
UG_GlobalMaxINT(const PPIF::PPIFContext & context,INT i)97 INT UG_GlobalMaxINT(const PPIF::PPIFContext& context, INT i)
98 {
99   MPI_Allreduce(MPI_IN_PLACE, &i, 1, MPI_INT, MPI_MAX, context.comm());
100   return i;
101 }
102 
103 /****************************************************************************/
104 /*D
105    UG_GlobalMinINT - get global minimum for INT value
106 
107    SYNOPSIS:
108    INT UG_GlobalMaxINT (INT i)
109 
110    PARAMETERS:
111    .  i - calculate minimum for this value
112 
113    DESCRIPTION:
114    This function calculates the minimum of i over all processors.
115 
116    RETURN VALUE:
117    The minimum value of i over all processors
118 
119    D*/
120 /****************************************************************************/
121 
UG_GlobalMinINT(const PPIF::PPIFContext & context,INT i)122 INT UG_GlobalMinINT (const PPIF::PPIFContext& context, INT i)
123 {
124   MPI_Allreduce(MPI_IN_PLACE, &i, 1, MPI_INT, MPI_MIN, context.comm());
125   return i;
126 }
127 
128 /****************************************************************************/
129 /*D
130    UG_GlobalSumINT - get global sum for INT value
131 
132    SYNOPSIS:
133    INT UG_GlobalSumINT (INT i)
134 
135    PARAMETERS:
136    .  i - calculate sum for this variable
137 
138    DESCRIPTION:
139    This function calculates the sum of i over all processors.
140 
141    RETURN VALUE:
142    The sum of i over all processors
143 
144    D*/
145 /****************************************************************************/
146 
UG_GlobalSumINT(const PPIF::PPIFContext & context,INT x)147 INT UG_GlobalSumINT (const PPIF::PPIFContext& context, INT x)
148 {
149   MPI_Allreduce(MPI_IN_PLACE, &x, 1, MPI_INT, MPI_SUM, context.comm());
150   return x;
151 }
152 
153 /****************************************************************************/
154 /*D
155    UG_GlobalMaxNINT - get maximum for n integer values
156 
157    SYNOPSIS:
158    void UG_GlobalMaxNINT (INT n, INT *x)
159 
160    PARAMETERS:
161    .  n - number of elements in array x to be used
162    .  x - array of size n
163 
164    DESCRIPTION:
165    This function calculates the maximum of x[i] over all processors for all
166    i from 0 to n-1. x is overwritten with the maximum value.
167 
168    RETURN VALUE:
169    none
170 
171    D*/
172 /****************************************************************************/
173 
UG_GlobalMaxNINT(const PPIF::PPIFContext & context,INT n,INT * x)174 void UG_GlobalMaxNINT(const PPIF::PPIFContext& context, INT n, INT *x)
175 {
176   MPI_Allreduce(MPI_IN_PLACE, x, n, MPI_INT, MPI_MAX, context.comm());
177 }
178 
179 /****************************************************************************/
180 /*D
181    UG_GlobalMinNINT - get minimum for n integer values
182 
183    SYNOPSIS:
184    void UG_GlobalMinNINT (INT n, INT *x)
185 
186    PARAMETERS:
187    .  n - number of elements in array x to be used
188    .  x - array of size n
189 
190    DESCRIPTION:
191    This function calculates the minimum of x[i] over all processors for all
192    i from 0 to n-1. x is overwritten with the minimum value.
193 
194    RETURN VALUE:
195    none
196 
197    D*/
198 /****************************************************************************/
199 
UG_GlobalMinNINT(const PPIF::PPIFContext & context,INT n,INT * x)200 void UG_GlobalMinNINT(const PPIF::PPIFContext& context, INT n, INT *x)
201 {
202   MPI_Allreduce(MPI_IN_PLACE, x, n, MPI_INT, MPI_MIN, context.comm());
203 }
204 
205 /****************************************************************************/
206 /*D
207    UG_GlobalSumNINT - calculate global sum for n integer values
208 
209    SYNOPSIS:
210    void UG_GlobalSumNINT (INT n, INT *x)
211 
212    PARAMETERS:
213    .  n - number of elements in array x to be used
214    .  x - array of size n
215 
216    DESCRIPTION:
217    This function calculates the sum of x[i] over all processors for each
218    i from 0 to n-1. x is overwritten with the result.
219 
220    RETURN VALUE:
221    none
222 
223    D*/
224 /****************************************************************************/
225 
UG_GlobalSumNINT(const PPIF::PPIFContext & context,INT n,INT * xs)226 void UG_GlobalSumNINT (const PPIF::PPIFContext& context, INT n, INT *xs)
227 {
228   MPI_Allreduce(MPI_IN_PLACE, xs, n, MPI_INT, MPI_SUM, context.comm());
229 }
230 
231 /****************************************************************************/
232 /*D
233    UG_GlobalMaxDOUBLE - get global maximum for DOUBLE value
234 
235    SYNOPSIS:
236    DOUBLE UG_GlobalMaxDOUBLE (DOUBLE x)
237 
238    PARAMETERS:
239    .  x - calculate maximum for this value
240 
241    DESCRIPTION:
242    This function calculates the maximum of x over all processors.
243 
244    RETURN VALUE:
245    The maximum value of x over all processors.
246 
247    D*/
248 /****************************************************************************/
249 
UG_GlobalMaxDOUBLE(const PPIF::PPIFContext & context,DOUBLE x)250 DOUBLE UG_GlobalMaxDOUBLE (const PPIF::PPIFContext& context, DOUBLE x)
251 {
252   MPI_Allreduce(MPI_IN_PLACE, &x, 1, MPI_DOUBLE, MPI_MAX, context.comm());
253   return x;
254 }
255 
256 /****************************************************************************/
257 /*D
258    UG_GlobalMinDOUBLE - get global minimum for DOUBLE value
259 
260    SYNOPSIS:
261    DOUBLE UG_GlobalMinDOUBLE (DOUBLE x)
262 
263    PARAMETERS:
264    .  x - calculate minimum for this value
265 
266    DESCRIPTION:
267    This function calculates the minimum of x over all processors.
268 
269    RETURN VALUE:
270    The minimum value of x over all processors.
271 
272    D*/
273 /****************************************************************************/
274 
UG_GlobalMinDOUBLE(const PPIF::PPIFContext & context,DOUBLE x)275 DOUBLE UG_GlobalMinDOUBLE (const PPIF::PPIFContext& context, DOUBLE x)
276 {
277   MPI_Allreduce(MPI_IN_PLACE, &x, 1, MPI_DOUBLE, MPI_MIN, context.comm());
278   return x;
279 }
280 
281 /****************************************************************************/
282 /*D
283    UG_GlobalSumDOUBLE - get global sum for DOUBLE value
284 
285    SYNOPSIS:
286    DOUBLE UG_GlobalSumDOUBLE (DOUBLE i)
287 
288    PARAMETERS:
289    .  i - calculate sum for this variable
290 
291    DESCRIPTION:
292    This function calculates the sum of i over all processors.
293 
294    RETURN VALUE:
295    The sum of i over all processors
296 
297    D*/
298 /****************************************************************************/
299 
UG_GlobalSumDOUBLE(const PPIF::PPIFContext & context,DOUBLE x)300 DOUBLE UG_GlobalSumDOUBLE (const PPIF::PPIFContext& context, DOUBLE x)
301 {
302   MPI_Allreduce(MPI_IN_PLACE, &x, 1, MPI_DOUBLE, MPI_SUM, context.comm());
303   return x;
304 }
305 
306 /****************************************************************************/
307 /*D
308    UG_GlobalMaxNDOUBLE - get maximum over n integer values
309 
310    SYNOPSIS:
311    void UG_GlobalMaxNDOUBLE (INT n, DOUBLE *x)
312 
313    PARAMETERS:
314    .  n - number of elements in array x to be used
315    .  x - array of size n
316 
317    DESCRIPTION:
318    This function calculates the maximum of x[i] over all processors for all
319    i from 0 to n-1. x is overwritten with the maximum value.
320 
321    RETURN VALUE:
322    none
323 
324    D*/
325 /****************************************************************************/
326 
UG_GlobalMaxNDOUBLE(const PPIF::PPIFContext & context,INT n,DOUBLE * x)327 void UG_GlobalMaxNDOUBLE (const PPIF::PPIFContext& context, INT n, DOUBLE *x)
328 {
329   MPI_Allreduce(MPI_IN_PLACE, x, n, MPI_DOUBLE, MPI_MAX, context.comm());
330 }
331 
332 /****************************************************************************/
333 /*D
334    UG_GlobalMinNDOUBLE - get minimum over n integer values
335 
336    SYNOPSIS:
337    void UG_GlobalMinNDOUBLE (INT n, DOUBLE *x)
338 
339    PARAMETERS:
340    .  n - number of elements in array x to be used
341    .  x - array of size n
342 
343    DESCRIPTION:
344    This function calculates the minimum of x[i] over all processors for all
345    i from 0 to n-1. x is overwritten with the minimum value.
346 
347    RETURN VALUE:
348    none
349 
350    D*/
351 /****************************************************************************/
352 
UG_GlobalMinNDOUBLE(const PPIF::PPIFContext & context,INT n,DOUBLE * x)353 void UG_GlobalMinNDOUBLE (const PPIF::PPIFContext& context, INT n, DOUBLE *x)
354 {
355   MPI_Allreduce(MPI_IN_PLACE, x, n, MPI_DOUBLE, MPI_MIN, context.comm());
356 }
357 
358 /****************************************************************************/
359 /*D
360    UG_GlobalSumNDOUBLE - calculate global sum for n DOUBLE values
361 
362    SYNOPSIS:
363    void UG_GlobalSumNDOUBLE (INT n, DOUBLE *x)
364 
365    PARAMETERS:
366    .  n - number of elements in array x to be used
367    .  x - array of size n
368 
369    DESCRIPTION:
370    This function calculates the sum of x[i] over all processors for each
371    i from 0 to n-1. x is overwritten with the result.
372 
373    RETURN VALUE:
374    none
375 
376    D*/
377 /****************************************************************************/
378 
UG_GlobalSumNDOUBLE(const PPIF::PPIFContext & context,INT n,DOUBLE * x)379 void UG_GlobalSumNDOUBLE (const PPIF::PPIFContext& context, INT n, DOUBLE *x)
380 {
381   MPI_Allreduce(MPI_IN_PLACE, x, n, MPI_DOUBLE, MPI_SUM, context.comm());
382 }
383 
384 #endif  /* ModelP */
385 
386 END_UGDIM_NAMESPACE
387