source: CIVL/examples/mpi-omp/AMG2013/struct_mv/communication_info.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 28.0 KB
Line 
1/*BHEADER**********************************************************************
2 * Copyright (c) 2008, Lawrence Livermore National Security, LLC.
3 * Produced at the Lawrence Livermore National Laboratory.
4 * This file is part of HYPRE. See file COPYRIGHT for details.
5 *
6 * HYPRE is free software; you can redistribute it and/or modify it under the
7 * terms of the GNU Lesser General Public License (as published by the Free
8 * Software Foundation) version 2.1 dated February 1999.
9 *
10 * $Revision: 2.4 $
11 ***********************************************************************EHEADER*/
12
13
14/******************************************************************************
15 *
16 *****************************************************************************/
17
18#include "headers.h"
19
20/*--------------------------------------------------------------------------
21 *--------------------------------------------------------------------------*/
22
23int
24hypre_CommInfoCreate( hypre_BoxArrayArray *send_boxes,
25 hypre_BoxArrayArray *recv_boxes,
26 int **send_procs,
27 int **recv_procs,
28 int **send_rboxnums,
29 int **recv_rboxnums,
30 hypre_BoxArrayArray *send_rboxes,
31 hypre_CommInfo **comm_info_ptr )
32{
33 int ierr = 0;
34 hypre_CommInfo *comm_info;
35
36 comm_info = hypre_TAlloc(hypre_CommInfo, 1);
37
38 hypre_CommInfoSendBoxes(comm_info) = send_boxes;
39 hypre_CommInfoRecvBoxes(comm_info) = recv_boxes;
40 hypre_CommInfoSendProcesses(comm_info) = send_procs;
41 hypre_CommInfoRecvProcesses(comm_info) = recv_procs;
42 hypre_CommInfoSendRBoxnums(comm_info) = send_rboxnums;
43 hypre_CommInfoRecvRBoxnums(comm_info) = recv_rboxnums;
44 hypre_CommInfoSendRBoxes(comm_info) = send_rboxes;
45
46 hypre_SetIndex(hypre_CommInfoSendStride(comm_info), 1, 1, 1);
47 hypre_SetIndex(hypre_CommInfoRecvStride(comm_info), 1, 1, 1);
48
49 *comm_info_ptr = comm_info;
50
51 return ierr;
52}
53
54/*--------------------------------------------------------------------------
55 *--------------------------------------------------------------------------*/
56
57int
58hypre_CommInfoProjectSend( hypre_CommInfo *comm_info,
59 hypre_Index index,
60 hypre_Index stride )
61{
62 int ierr = 0;
63
64 hypre_ProjectBoxArrayArray(hypre_CommInfoSendBoxes(comm_info),
65 index, stride);
66 hypre_ProjectBoxArrayArray(hypre_CommInfoSendRBoxes(comm_info),
67 index, stride);
68 hypre_CopyIndex(stride, hypre_CommInfoSendStride(comm_info));
69
70 return ierr;
71}
72
73/*--------------------------------------------------------------------------
74 *--------------------------------------------------------------------------*/
75
76int
77hypre_CommInfoProjectRecv( hypre_CommInfo *comm_info,
78 hypre_Index index,
79 hypre_Index stride )
80{
81 int ierr = 0;
82
83 hypre_ProjectBoxArrayArray(hypre_CommInfoRecvBoxes(comm_info),
84 index, stride);
85 hypre_CopyIndex(stride, hypre_CommInfoRecvStride(comm_info));
86
87 return ierr;
88}
89
90/*--------------------------------------------------------------------------
91 *--------------------------------------------------------------------------*/
92
93int
94hypre_CommInfoDestroy( hypre_CommInfo *comm_info )
95{
96 int ierr = 0;
97 hypre_BoxArrayArray *boxes;
98 int **procs;
99 int **boxnums;
100 hypre_BoxArrayArray *rboxes;
101 int i;
102
103 boxes = hypre_CommInfoSendBoxes(comm_info);
104 procs = hypre_CommInfoSendProcesses(comm_info);
105 boxnums = hypre_CommInfoSendRBoxnums(comm_info);
106 rboxes = hypre_CommInfoSendRBoxes(comm_info);
107 hypre_ForBoxArrayI(i, boxes)
108 {
109 hypre_TFree(procs[i]);
110 hypre_TFree(boxnums[i]);
111 }
112 hypre_BoxArrayArrayDestroy(boxes);
113 hypre_BoxArrayArrayDestroy(rboxes);
114 hypre_TFree(procs);
115 hypre_TFree(boxnums);
116
117 boxes = hypre_CommInfoRecvBoxes(comm_info);
118 procs = hypre_CommInfoRecvProcesses(comm_info);
119 boxnums = hypre_CommInfoRecvRBoxnums(comm_info);
120 hypre_ForBoxArrayI(i, boxes)
121 {
122 hypre_TFree(procs[i]);
123 if (boxnums[i])
124 hypre_TFree(boxnums[i]);
125 }
126 hypre_BoxArrayArrayDestroy(boxes);
127 hypre_TFree(procs);
128 if (boxnums)
129 hypre_TFree(boxnums);
130
131 hypre_TFree(comm_info);
132
133 return ierr;
134}
135
136/*--------------------------------------------------------------------------
137 * Return descriptions of communications patterns for a given
138 * grid-stencil computation. These patterns are defined by
139 * intersecting the data dependencies of each box (including data
140 * dependencies within the box) with its neighbor boxes.
141 *
142 * An inconsistent ordering of the boxes in the send/recv data regions
143 * is returned. That is, the ordering of the boxes on process p for
144 * receives from process q is not guaranteed to be the same as the
145 * ordering of the boxes on process q for sends to process p.
146 *
147 * The routine uses a grow-the-box-and-intersect-with-neighbors style
148 * algorithm that eliminates the need for the UnionBoxes routine used
149 * in previous implementations.
150 *
151 * 1. The basic algorithm:
152 *
153 * The basic algorithm is as follows, with one additional optimization
154 * discussed below that helps to minimize the number of communications
155 * that are done with neighbors (e.g., consider a 7-pt stencil and the
156 * difference between doing 26 communications versus 6):
157 *
158 * To compute send/recv regions, do
159 *
160 * for i = local box
161 * {
162 * // receives
163 * for j = neighbor box of i
164 * {
165 * gbox = grow box i according to stencil
166 * intersect gbox with box j and add to recv region
167 * }
168 *
169 * // sends
170 * for j = neighbor box of i
171 * {
172 * gbox = grow box j according to stencil
173 * intersect gbox with box i and add to send region
174 * }
175 * }
176 *
177 * sort the send boxes by j index first (this can be done cheaply)
178 *
179 * 2. Optimization on basic algorithm:
180 *
181 * Before looping over the neighbors in the above algorithm, do a
182 * preliminary sweep through the neighbors to select a subset of
183 * neighbors to do the intersections with. To select the subset,
184 * compute a so-called "distance index" and check the corresponding
185 * entry in the so-called "stencil grid" to decide whether or not to
186 * use the box.
187 *
188 * The "stencil grid" is a 3x3x3 grid in 3D that is built from the
189 * stencil as follows:
190 *
191 * // assume for simplicity that i,j,k are -1, 0, or 1
192 * for each stencil entry (i,j,k)
193 * {
194 * mark all stencil grid entries in (1,1,1) x (1+i,1+j,1+k)
195 * // here (1,1,1) is the "center" entry in the stencil grid
196 * }
197 *
198 * 3. Complications with periodicity:
199 *
200 * When periodicity is on, it is possible to have a box-pair region
201 * (the description of a communication pattern between two boxes) that
202 * consists of more than one box.
203 *
204 * NOTE: It is assumed that the grids neighbor information is
205 * sufficiently large.
206 *
207 * NOTE: No concept of data ownership is assumed. As a result,
208 * redundant communication patterns can be produced when the grid
209 * boxes overlap.
210 *
211 *
212 * CHANGEs for "HYPRE_NO_GLOBAL_PARTITION":
213 * Changes made for use with the assumed partition
214 * because (1) we may not have ALL the perioic boxes corresponding to a single box
215 * in neighbor->boxes (2) we may have a periodic box but not the "real" box
216 *
217 *
218 *--------------------------------------------------------------------------*/
219
220
221
222
223#ifdef HYPRE_NO_GLOBAL_PARTITION
224
225#define hypre_NewBeginBoxNeighborsLoop(n, neighbors, b, prank) \
226{\
227 hypre_RankLink *hypre__rank_link;\
228\
229 hypre__rank_link = hypre_BoxNeighborsRankLink(neighbors, b);\
230 while (hypre__rank_link)\
231 {\
232 n = hypre_RankLinkRank(hypre__rank_link);\
233 prank = hypre_RankLinkPRank(hypre__rank_link);
234
235
236#endif
237
238int
239hypre_CreateCommInfoFromStencil( hypre_StructGrid *grid,
240 hypre_StructStencil *stencil,
241 hypre_CommInfo **comm_info_ptr )
242{
243 int ierr = 0;
244
245 hypre_BoxArrayArray *send_boxes;
246 hypre_BoxArrayArray *recv_boxes;
247 int **send_procs;
248 int **recv_procs;
249 int **send_rboxnums;
250 int **recv_rboxnums;
251 hypre_BoxArrayArray *send_rboxes;
252
253 hypre_BoxArray *boxes = hypre_StructGridBoxes(grid);
254 int num_boxes = hypre_BoxArraySize(boxes);
255
256 hypre_BoxNeighbors *neighbors = hypre_StructGridNeighbors(grid);
257 hypre_BoxArray *hood_boxes = hypre_BoxNeighborsBoxes(neighbors);
258 int *hood_procs = hypre_BoxNeighborsProcs(neighbors);
259 int *hood_boxnums = hypre_BoxNeighborsBoxnums(neighbors);
260 int num_hood;
261
262 hypre_Index *stencil_shape;
263 hypre_IndexRef stencil_offset;
264 hypre_IndexRef pshift;
265
266 hypre_Box *box;
267 hypre_Box *hood_box;
268 hypre_Box *grow_box;
269 hypre_Box *int_box;
270
271 int stencil_grid[3][3][3];
272 int grow[3][2];
273
274 hypre_BoxArray *send_box_array;
275 hypre_BoxArray *recv_box_array;
276 int send_box_array_size;
277 int recv_box_array_size;
278 hypre_BoxArray *send_rbox_array;
279
280 hypre_Box **cboxes;
281 hypre_Box *cboxes_mem;
282 int *cboxes_j;
283 int num_cboxes;
284 hypre_BoxArray **cper_arrays;
285 int cper_array_size;
286
287 int i, j, k, m, n, p;
288 int s, d, lastj;
289 int istart[3], istop[3];
290 int sgindex[3];
291
292 /*------------------------------------------------------
293 * Compute the "stencil grid" and "grow" information
294 *------------------------------------------------------*/
295
296 stencil_shape = hypre_StructStencilShape(stencil);
297
298 for (k = 0; k < 3; k++)
299 {
300 for (j = 0; j < 3; j++)
301 {
302 for (i = 0; i < 3; i++)
303 {
304 stencil_grid[i][j][k] = 0;
305 }
306 }
307 }
308
309 for (d = 0; d < 3; d++)
310 {
311 grow[d][0] = 0;
312 grow[d][1] = 0;
313 }
314
315 for (s = 0; s < hypre_StructStencilSize(stencil); s++)
316 {
317 stencil_offset = stencil_shape[s];
318
319 for (d = 0; d < 3; d++)
320 {
321 m = stencil_offset[d];
322
323 istart[d] = 1;
324 istop[d] = 1;
325
326 if (m < 0)
327 {
328 istart[d] = 0;
329 grow[d][0] = hypre_max(grow[d][0], -m);
330 }
331 else if (m > 0)
332 {
333 istop[d] = 2;
334 grow[d][1] = hypre_max(grow[d][1], m);
335 }
336 }
337
338 for (k = istart[2]; k <= istop[2]; k++)
339 {
340 for (j = istart[1]; j <= istop[1]; j++)
341 {
342 for (i = istart[0]; i <= istop[0]; i++)
343 {
344 stencil_grid[i][j][k] = 1;
345 }
346 }
347 }
348 }
349
350 /*------------------------------------------------------
351 * Compute send/recv boxes and procs
352 *------------------------------------------------------*/
353
354 send_boxes = hypre_BoxArrayArrayCreate(hypre_BoxArraySize(boxes));
355 recv_boxes = hypre_BoxArrayArrayCreate(hypre_BoxArraySize(boxes));
356 send_procs = hypre_CTAlloc(int *, hypre_BoxArraySize(boxes));
357 recv_procs = hypre_CTAlloc(int *, hypre_BoxArraySize(boxes));
358 send_rboxnums = hypre_CTAlloc(int *, hypre_BoxArraySize(boxes));
359 send_rboxes = hypre_BoxArrayArrayCreate(hypre_BoxArraySize(boxes));
360
361 /* recv_rboxnums is needed for inverse communication, i.e., switch
362 send_ <=> recv_ and create the inverse communication as before. */
363 recv_rboxnums = hypre_CTAlloc(int *, hypre_BoxArraySize(boxes));
364
365 grow_box = hypre_BoxCreate();
366 int_box = hypre_BoxCreate();
367
368#ifdef HYPRE_NO_GLOBAL_PARTITION
369 num_hood = hypre_BoxArraySize(hood_boxes);
370#else
371 num_hood = hypre_BoxArraySize(hood_boxes) /
372 hypre_BoxNeighborsNumPeriods(neighbors);
373#endif
374 cboxes = hypre_CTAlloc(hypre_Box *, num_hood);
375 cboxes_mem = hypre_CTAlloc(hypre_Box, num_hood);
376 cboxes_j = hypre_CTAlloc(int, num_hood);
377 cper_arrays = hypre_CTAlloc(hypre_BoxArray *, num_hood);
378
379 for (i = 0; i < num_boxes; i++)
380 {
381 box = hypre_BoxArrayBox(boxes, i);
382
383 /*------------------------------------------------
384 * Compute recv_box_array for box i
385 *------------------------------------------------*/
386
387 /* grow box */
388 hypre_CopyBox(box, grow_box);
389 for (d = 0; d < 3; d++)
390 {
391 hypre_BoxIMinD(grow_box, d) -= grow[d][0];
392 hypre_BoxIMaxD(grow_box, d) += grow[d][1];
393 }
394
395 lastj = -1;
396 num_cboxes = 0;
397 recv_box_array_size = 0;
398#ifdef HYPRE_NO_GLOBAL_PARTITION
399 /* note: now we may not have all the periodic boxes periodic*/
400 hypre_NewBeginBoxNeighborsLoop(k, neighbors, i, p)
401#else
402 hypre_BeginBoxNeighborsLoop(k, neighbors, i)
403#endif
404 {
405 hood_box = hypre_BoxArrayBox(hood_boxes, k);
406
407 for (d = 0; d < 3; d++)
408 {
409 sgindex[d] = 1;
410
411 s = hypre_BoxIMinD(hood_box, d) - hypre_BoxIMaxD(box, d);
412 if (s > 0)
413 {
414 sgindex[d] = 2;
415 }
416 s = hypre_BoxIMinD(box, d) - hypre_BoxIMaxD(hood_box, d);
417 if (s > 0)
418 {
419 sgindex[d] = 0;
420 }
421 }
422
423 if (stencil_grid[sgindex[0]][sgindex[1]][sgindex[2]])
424 {
425 /* intersect */
426 hypre_IntersectBoxes(grow_box, hood_box, int_box);
427
428 if (hypre_BoxVolume(int_box))
429 {
430#ifdef HYPRE_NO_GLOBAL_PARTITION
431 j = k ; /* don't need to account for periodic here*/
432#else
433 j = k % num_hood;
434 if (j != lastj)
435#endif
436 {
437 cboxes_j[num_cboxes] = j;
438 num_cboxes++;
439 lastj = j;
440 }
441 recv_box_array_size++;
442
443#ifdef HYPRE_NO_GLOBAL_PARTITION
444 /* the neighbor was not periodic */
445 cboxes[j] = &cboxes_mem[j];
446 hypre_CopyBox(int_box, cboxes[j]);
447
448#else
449 if (k < num_hood)
450
451 {
452 /* the neighbor was not periodic */
453 cboxes[j] = &cboxes_mem[j];
454 hypre_CopyBox(int_box, cboxes[j]);
455 }
456 else
457 {
458 /* the neighbor was periodic */
459 if (cper_arrays[j] == NULL)
460 {
461 cper_arrays[j] = hypre_BoxArrayCreate(26);
462 hypre_BoxArraySetSize(cper_arrays[j], 0);
463 }
464 hypre_AppendBox(int_box, cper_arrays[j]);
465 }
466#endif
467
468 }
469 }
470 }
471 hypre_EndBoxNeighborsLoop;
472
473 /* create recv_box_array and recv_procs */
474 recv_box_array = hypre_BoxArrayArrayBoxArray(recv_boxes, i);
475 hypre_BoxArraySetSize(recv_box_array, recv_box_array_size);
476 recv_procs[i] = hypre_CTAlloc(int, recv_box_array_size);
477 recv_rboxnums[i] = hypre_CTAlloc(int, recv_box_array_size);
478 n = 0;
479 for (m = 0; m < num_cboxes; m++)
480 {
481 j = cboxes_j[m];
482
483#ifdef HYPRE_NO_GLOBAL_PARTITION
484 /* add the non-periodic box */
485 recv_procs[i][n] = hood_procs[j];
486 recv_rboxnums[i][n] = hood_boxnums[j];
487 hypre_CopyBox(cboxes[j], hypre_BoxArrayBox(recv_box_array, n));
488 n++;
489 cboxes[j] = NULL;
490#else
491 /* add the non-periodic box */
492 if (cboxes[j] != NULL)
493 {
494 recv_procs[i][n] = hood_procs[j];
495 recv_rboxnums[i][n] = hood_boxnums[j];
496 hypre_CopyBox(cboxes[j], hypre_BoxArrayBox(recv_box_array, n));
497 n++;
498 cboxes[j] = NULL;
499 }
500
501 /* add the periodic boxes */
502 if (cper_arrays[j] != NULL)
503 {
504 cper_array_size = hypre_BoxArraySize(cper_arrays[j]);
505 for (k = 0; k < cper_array_size; k++)
506 {
507 recv_procs[i][n] = hood_procs[j];
508 recv_rboxnums[i][n] = hood_boxnums[j];
509 hypre_CopyBox(hypre_BoxArrayBox(cper_arrays[j], k),
510 hypre_BoxArrayBox(recv_box_array, n));
511 n++;
512 }
513 hypre_BoxArrayDestroy(cper_arrays[j]);
514 cper_arrays[j] = NULL;
515 }
516#endif
517 }
518
519 /*------------------------------------------------
520 * Compute send_box_array for box i
521 *------------------------------------------------*/
522
523 lastj = -1;
524 num_cboxes = 0;
525 send_box_array_size = 0;
526#ifdef HYPRE_NO_GLOBAL_PARTITION
527 hypre_NewBeginBoxNeighborsLoop(k, neighbors, i, p)
528#else
529 hypre_BeginBoxNeighborsLoop(k, neighbors, i)
530#endif
531 {
532 hood_box = hypre_BoxArrayBox(hood_boxes, k);
533
534 for (d = 0; d < 3; d++)
535 {
536 sgindex[d] = 1;
537
538 s = hypre_BoxIMinD(box, d) - hypre_BoxIMaxD(hood_box, d);
539 if (s > 0)
540 {
541 sgindex[d] = 2;
542 }
543 s = hypre_BoxIMinD(hood_box, d) - hypre_BoxIMaxD(box, d);
544 if (s > 0)
545 {
546 sgindex[d] = 0;
547 }
548 }
549
550 if (stencil_grid[sgindex[0]][sgindex[1]][sgindex[2]])
551 {
552 /* grow box and intersect */
553 hypre_CopyBox(hood_box, grow_box);
554 for (d = 0; d < 3; d++)
555 {
556 hypre_BoxIMinD(grow_box, d) -= grow[d][0];
557 hypre_BoxIMaxD(grow_box, d) += grow[d][1];
558 }
559 hypre_IntersectBoxes(box, grow_box, int_box);
560
561 if (hypre_BoxVolume(int_box))
562 {
563#ifdef HYPRE_NO_GLOBAL_PARTITION
564 j = k ; /* don't need to account for periodic here*/
565#else
566 j = k % num_hood;
567 if (j != lastj)
568#endif
569 {
570 cboxes_j[num_cboxes] = j;
571 num_cboxes++;
572 lastj = j;
573 }
574 send_box_array_size++;
575 /* get which periodic box this is so we know how to shift */
576#ifdef HYPRE_NO_GLOBAL_PARTITION
577 if (p==0)
578#else
579 if (k < num_hood)
580#endif
581 {
582 /* the neighbor was not periodic */
583 cboxes[j] = &cboxes_mem[j];
584 hypre_CopyBox(int_box, cboxes[j]);
585 }
586 else
587 {
588 /* the neighbor was periodic */
589 if (cper_arrays[j] == NULL)
590 {
591 cper_arrays[j] = hypre_BoxArrayCreate(26);
592 hypre_BoxArraySetSize(cper_arrays[j], 0);
593 }
594 hypre_AppendBox(int_box, cper_arrays[j]);
595#ifndef HYPRE_NO_GLOBAL_PARTITION
596 p = k / num_hood;
597#endif
598 pshift = hypre_BoxNeighborsPShift(neighbors, p);
599 hypre_BoxShiftNeg(int_box, pshift);
600 hypre_AppendBox(int_box, cper_arrays[j]);
601 }
602 }
603 }
604 }
605 hypre_EndBoxNeighborsLoop;
606
607 /* create send_box_array and send_procs */
608 send_box_array = hypre_BoxArrayArrayBoxArray(send_boxes, i);
609 hypre_BoxArraySetSize(send_box_array, send_box_array_size);
610 send_procs[i] = hypre_CTAlloc(int, send_box_array_size);
611 send_rboxnums[i] = hypre_CTAlloc(int, send_box_array_size);
612 send_rbox_array = hypre_BoxArrayArrayBoxArray(send_rboxes, i);
613 hypre_BoxArraySetSize(send_rbox_array, send_box_array_size);
614 n = 0;
615 for (m = 0; m < num_cboxes; m++)
616 {
617 j = cboxes_j[m];
618
619 /* add the non-periodic box */
620 if (cboxes[j] != NULL)
621 {
622 send_procs[i][n] = hood_procs[j];
623 send_rboxnums[i][n] = hood_boxnums[j];
624 hypre_CopyBox(cboxes[j], hypre_BoxArrayBox(send_box_array, n));
625 hypre_CopyBox(cboxes[j], hypre_BoxArrayBox(send_rbox_array, n));
626 n++;
627 cboxes[j] = NULL;
628 }
629
630 /* add the periodic boxes */
631 if (cper_arrays[j] != NULL)
632 {
633 cper_array_size = hypre_BoxArraySize(cper_arrays[j]);
634 for (k = 0; k < (cper_array_size / 2); k++)
635 {
636 send_procs[i][n] = hood_procs[j];
637 send_rboxnums[i][n] = hood_boxnums[j];
638 hypre_CopyBox(hypre_BoxArrayBox(cper_arrays[j], 2*k),
639 hypre_BoxArrayBox(send_box_array, n));
640 hypre_CopyBox(hypre_BoxArrayBox(cper_arrays[j], 2*k+1),
641 hypre_BoxArrayBox(send_rbox_array, n));
642 n++;
643 }
644 hypre_BoxArrayDestroy(cper_arrays[j]);
645 cper_arrays[j] = NULL;
646 }
647 }
648 }
649
650 hypre_TFree(cboxes);
651 hypre_TFree(cboxes_mem);
652 hypre_TFree(cboxes_j);
653 hypre_TFree(cper_arrays);
654
655 hypre_BoxDestroy(grow_box);
656 hypre_BoxDestroy(int_box);
657
658 /*------------------------------------------------------
659 * Return
660 *------------------------------------------------------*/
661
662 hypre_CommInfoCreate(send_boxes, recv_boxes, send_procs, recv_procs,
663 send_rboxnums, recv_rboxnums, send_rboxes, comm_info_ptr);
664
665 return ierr;
666}
667
668/*--------------------------------------------------------------------------
669 * Return descriptions of communications patterns for a given grid
670 * based on a specified number of "ghost zones". These patterns are
671 * defined by building a stencil and calling CommInfoFromStencil.
672 *--------------------------------------------------------------------------*/
673
674int
675hypre_CreateCommInfoFromNumGhost( hypre_StructGrid *grid,
676 int *num_ghost,
677 hypre_CommInfo **comm_info_ptr )
678{
679 int ierr = 0;
680
681 hypre_StructStencil *stencil;
682 hypre_Index *stencil_shape;
683 int startstop[6], ii[3], i, d, size;
684
685 stencil_shape = hypre_CTAlloc(hypre_Index, 27);
686 for (i = 0; i < 6; i++)
687 {
688 startstop[i] = num_ghost[i] ? 1 : 0;
689 }
690 size = 0;
691 for (ii[2] = -startstop[4]; ii[2] <= startstop[5]; ii[2]++)
692 {
693 for (ii[1] = -startstop[2]; ii[1] <= startstop[3]; ii[1]++)
694 {
695 for (ii[0] = -startstop[0]; ii[0] <= startstop[1]; ii[0]++)
696 {
697 for (d = 0; d < 3; d++)
698 {
699 if (ii[d] < 0)
700 {
701 stencil_shape[size][d] = -num_ghost[2*d];
702 }
703 else if (ii[d] > 0)
704 {
705 stencil_shape[size][d] = num_ghost[2*d+1];
706 }
707 }
708 size++;
709 }
710 }
711 }
712 stencil = hypre_StructStencilCreate(3, size, stencil_shape);
713
714 hypre_CreateCommInfoFromStencil(grid, stencil, comm_info_ptr);
715
716 hypre_StructStencilDestroy(stencil);
717
718 return ierr;
719}
720
721/*--------------------------------------------------------------------------
722 * Return descriptions of communications patterns for migrating data
723 * from one grid distribution to another.
724 *--------------------------------------------------------------------------*/
725
726int
727hypre_CreateCommInfoFromGrids( hypre_StructGrid *from_grid,
728 hypre_StructGrid *to_grid,
729 hypre_CommInfo **comm_info_ptr )
730{
731 int ierr = 0;
732
733 hypre_BoxArrayArray *send_boxes;
734 hypre_BoxArrayArray *recv_boxes;
735 int **send_procs;
736 int **recv_procs;
737 int **send_rboxnums;
738 int **recv_rboxnums;
739 hypre_BoxArrayArray *send_rboxes;
740
741 hypre_BoxArrayArray *comm_boxes;
742 int **comm_procs;
743 int **comm_boxnums;
744 hypre_BoxArray *comm_box_array;
745 hypre_Box *comm_box;
746
747 hypre_StructGrid *local_grid;
748 hypre_StructGrid *remote_grid;
749
750 hypre_BoxArray *local_boxes;
751 hypre_BoxArray *remote_boxes;
752 hypre_BoxArray *remote_all_boxes;
753 int *remote_all_procs;
754 int *remote_all_boxnums;
755 int remote_first_local;
756
757 hypre_Box *local_box;
758 hypre_Box *remote_box;
759
760 int i, j, k, r;
761
762 /*------------------------------------------------------
763 * Set up communication info
764 *------------------------------------------------------*/
765
766 for (r = 0; r < 2; r++)
767 {
768 switch(r)
769 {
770 case 0:
771 local_grid = from_grid;
772 remote_grid = to_grid;
773 break;
774
775 case 1:
776 local_grid = to_grid;
777 remote_grid = from_grid;
778 break;
779 }
780
781 /*---------------------------------------------------
782 * Compute comm_boxes and comm_procs
783 *---------------------------------------------------*/
784
785 local_boxes = hypre_StructGridBoxes(local_grid);
786 remote_boxes = hypre_StructGridBoxes(remote_grid);
787 hypre_GatherAllBoxes(hypre_StructGridComm(remote_grid), remote_boxes,
788 &remote_all_boxes,
789 &remote_all_procs,
790 &remote_first_local);
791 hypre_ComputeBoxnums(remote_all_boxes, remote_all_procs,
792 &remote_all_boxnums);
793
794 comm_boxes = hypre_BoxArrayArrayCreate(hypre_BoxArraySize(local_boxes));
795 comm_procs = hypre_CTAlloc(int *, hypre_BoxArraySize(local_boxes));
796 comm_boxnums = hypre_CTAlloc(int *, hypre_BoxArraySize(local_boxes));
797
798 comm_box = hypre_BoxCreate();
799 hypre_ForBoxI(i, local_boxes)
800 {
801 local_box = hypre_BoxArrayBox(local_boxes, i);
802
803 comm_box_array = hypre_BoxArrayArrayBoxArray(comm_boxes, i);
804 comm_procs[i] =
805 hypre_CTAlloc(int, hypre_BoxArraySize(remote_all_boxes));
806 comm_boxnums[i] =
807 hypre_CTAlloc(int, hypre_BoxArraySize(remote_all_boxes));
808
809 hypre_ForBoxI(j, remote_all_boxes)
810 {
811 remote_box = hypre_BoxArrayBox(remote_all_boxes, j);
812
813 hypre_IntersectBoxes(local_box, remote_box, comm_box);
814 if (hypre_BoxVolume(comm_box))
815 {
816 k = hypre_BoxArraySize(comm_box_array);
817 comm_procs[i][k] = remote_all_procs[j];
818 comm_boxnums[i][k] = remote_all_boxnums[j];
819
820 hypre_AppendBox(comm_box, comm_box_array);
821 }
822 }
823
824 comm_procs[i] =
825 hypre_TReAlloc(comm_procs[i],
826 int, hypre_BoxArraySize(comm_box_array));
827 comm_boxnums[i] =
828 hypre_TReAlloc(comm_boxnums[i],
829 int, hypre_BoxArraySize(comm_box_array));
830 }
831 hypre_BoxDestroy(comm_box);
832
833 hypre_BoxArrayDestroy(remote_all_boxes);
834 hypre_TFree(remote_all_procs);
835 hypre_TFree(remote_all_boxnums);
836
837 switch(r)
838 {
839 case 0:
840 send_boxes = comm_boxes;
841 send_procs = comm_procs;
842 send_rboxnums = comm_boxnums;
843 send_rboxes = hypre_BoxArrayArrayDuplicate(comm_boxes);
844 break;
845
846 case 1:
847 recv_boxes = comm_boxes;
848 recv_procs = comm_procs;
849 recv_rboxnums = comm_boxnums;
850 break;
851 }
852 }
853
854 hypre_CommInfoCreate(send_boxes, recv_boxes, send_procs, recv_procs,
855 send_rboxnums, recv_rboxnums, send_rboxes, comm_info_ptr);
856
857 return ierr;
858}
Note: See TracBrowser for help on using the repository browser.