1 /******************************************************************************
2 * Copyright 1998-2019 Lawrence Livermore National Security, LLC and other
3 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
4 *
5 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
6 ******************************************************************************/
7
8 /******************************************************************************
9 *
10 * Member functions for hypre_StructGrid class.
11 *
12 *****************************************************************************/
13
14 #include "_hypre_struct_mv.h"
15
16 #define DEBUG 0
17
18 #if DEBUG
19 char filename[255];
20 FILE *file;
21 HYPRE_Int my_rank;
22 #endif
23
24 static HYPRE_Int time_index = 0;
25
26 /*--------------------------------------------------------------------------
27 * hypre_StructGridCreate
28 *--------------------------------------------------------------------------*/
29
30 HYPRE_Int
hypre_StructGridCreate(MPI_Comm comm,HYPRE_Int ndim,hypre_StructGrid ** grid_ptr)31 hypre_StructGridCreate( MPI_Comm comm,
32 HYPRE_Int ndim,
33 hypre_StructGrid **grid_ptr)
34 {
35 hypre_StructGrid *grid;
36 HYPRE_Int i;
37
38 grid = hypre_TAlloc(hypre_StructGrid, 1, HYPRE_MEMORY_HOST);
39
40 hypre_StructGridComm(grid) = comm;
41 hypre_StructGridNDim(grid) = ndim;
42 hypre_StructGridBoxes(grid) = hypre_BoxArrayCreate(0, ndim);
43 hypre_StructGridIDs(grid) = NULL;
44
45 hypre_SetIndex(hypre_StructGridMaxDistance(grid),8);
46
47 hypre_StructGridBoundingBox(grid) = NULL;
48 hypre_StructGridLocalSize(grid) = 0;
49 hypre_StructGridGlobalSize(grid) = 0;
50 hypre_SetIndex(hypre_StructGridPeriodic(grid), 0);
51 hypre_StructGridRefCount(grid) = 1;
52 hypre_StructGridBoxMan(grid) = NULL;
53
54 hypre_StructGridNumPeriods(grid) = 1;
55 hypre_StructGridPShifts(grid) = NULL;
56
57 hypre_StructGridGhlocalSize(grid) = 0;
58 for (i = 0; i < 2*ndim; i++)
59 {
60 hypre_StructGridNumGhost(grid)[i] = 1;
61 }
62
63 #if 0 //defined(HYPRE_USING_CUDA) || defined(HYPRE_USING_HIP)
64 hypre_StructGridDataLocation(grid) = HYPRE_MEMORY_DEVICE;
65 #endif
66 *grid_ptr = grid;
67
68 return hypre_error_flag;
69 }
70
71 /*--------------------------------------------------------------------------
72 * hypre_StructGridRef
73 *--------------------------------------------------------------------------*/
74
75 HYPRE_Int
hypre_StructGridRef(hypre_StructGrid * grid,hypre_StructGrid ** grid_ref)76 hypre_StructGridRef( hypre_StructGrid *grid,
77 hypre_StructGrid **grid_ref)
78 {
79 hypre_StructGridRefCount(grid) ++;
80 *grid_ref = grid;
81
82 return hypre_error_flag;
83 }
84
85 /*--------------------------------------------------------------------------
86 * hypre_StructGridDestroy
87 *--------------------------------------------------------------------------*/
88
89 HYPRE_Int
hypre_StructGridDestroy(hypre_StructGrid * grid)90 hypre_StructGridDestroy( hypre_StructGrid *grid )
91 {
92 if (grid)
93 {
94 hypre_StructGridRefCount(grid) --;
95 if (hypre_StructGridRefCount(grid) == 0)
96 {
97 hypre_BoxDestroy(hypre_StructGridBoundingBox(grid));
98 hypre_TFree(hypre_StructGridIDs(grid), HYPRE_MEMORY_HOST);
99 hypre_BoxArrayDestroy(hypre_StructGridBoxes(grid));
100
101 hypre_BoxManDestroy(hypre_StructGridBoxMan(grid));
102 hypre_TFree( hypre_StructGridPShifts(grid), HYPRE_MEMORY_HOST);
103
104 hypre_TFree(grid, HYPRE_MEMORY_HOST);
105 }
106 }
107
108 return hypre_error_flag;
109 }
110
111
112 /*--------------------------------------------------------------------------
113 * hypre_StructGridSetPeriodic
114 *--------------------------------------------------------------------------*/
115
116 HYPRE_Int
hypre_StructGridSetPeriodic(hypre_StructGrid * grid,hypre_Index periodic)117 hypre_StructGridSetPeriodic( hypre_StructGrid *grid,
118 hypre_Index periodic)
119 {
120 hypre_CopyIndex(periodic, hypre_StructGridPeriodic(grid));
121
122 return hypre_error_flag;
123 }
124
125 /*--------------------------------------------------------------------------
126 * hypre_StructGridSetExtents
127 *--------------------------------------------------------------------------*/
128
129 HYPRE_Int
hypre_StructGridSetExtents(hypre_StructGrid * grid,hypre_Index ilower,hypre_Index iupper)130 hypre_StructGridSetExtents( hypre_StructGrid *grid,
131 hypre_Index ilower,
132 hypre_Index iupper )
133 {
134 hypre_Box *box;
135
136 box = hypre_BoxCreate(hypre_StructGridNDim(grid));
137 hypre_BoxSetExtents(box, ilower, iupper);
138 hypre_AppendBox(box, hypre_StructGridBoxes(grid));
139 hypre_BoxDestroy(box);
140
141 return hypre_error_flag;
142 }
143
144 /*--------------------------------------------------------------------------
145 * hypre_StructGridSetBoxes
146 *--------------------------------------------------------------------------*/
147
148 HYPRE_Int
hypre_StructGridSetBoxes(hypre_StructGrid * grid,hypre_BoxArray * boxes)149 hypre_StructGridSetBoxes( hypre_StructGrid *grid,
150 hypre_BoxArray *boxes )
151 {
152
153 hypre_TFree(hypre_StructGridBoxes(grid), HYPRE_MEMORY_HOST);
154 hypre_StructGridBoxes(grid) = boxes;
155
156 return hypre_error_flag;
157 }
158
159 /*--------------------------------------------------------------------------
160 * hypre_StructGridSetBoundingBox
161 *--------------------------------------------------------------------------*/
162
163 HYPRE_Int
hypre_StructGridSetBoundingBox(hypre_StructGrid * grid,hypre_Box * new_bb)164 hypre_StructGridSetBoundingBox( hypre_StructGrid *grid,
165 hypre_Box *new_bb )
166 {
167
168 hypre_BoxDestroy(hypre_StructGridBoundingBox(grid));
169 hypre_StructGridBoundingBox(grid) = hypre_BoxDuplicate(new_bb);
170
171 return hypre_error_flag;
172 }
173
174 /*--------------------------------------------------------------------------
175 * hypre_StructGridSetIDs
176 *--------------------------------------------------------------------------*/
177
178 HYPRE_Int
hypre_StructGridSetIDs(hypre_StructGrid * grid,HYPRE_Int * ids)179 hypre_StructGridSetIDs( hypre_StructGrid *grid,
180 HYPRE_Int *ids )
181 {
182 hypre_TFree(hypre_StructGridIDs(grid), HYPRE_MEMORY_HOST);
183 hypre_StructGridIDs(grid) = ids;
184
185 return hypre_error_flag;
186 }
187
188 /*--------------------------------------------------------------------------
189 * hypre_StructGridSetBoxManager
190 *--------------------------------------------------------------------------*/
191
192 HYPRE_Int
hypre_StructGridSetBoxManager(hypre_StructGrid * grid,hypre_BoxManager * boxman)193 hypre_StructGridSetBoxManager( hypre_StructGrid *grid,
194 hypre_BoxManager *boxman )
195 {
196
197 hypre_TFree(hypre_StructGridBoxMan(grid), HYPRE_MEMORY_HOST);
198 hypre_StructGridBoxMan(grid) = boxman;
199
200 return hypre_error_flag;
201 }
202
203 /*--------------------------------------------------------------------------
204 * hypre_StructGridSetMaxDistance
205 *--------------------------------------------------------------------------*/
206
207 HYPRE_Int
hypre_StructGridSetMaxDistance(hypre_StructGrid * grid,hypre_Index dist)208 hypre_StructGridSetMaxDistance( hypre_StructGrid *grid,
209 hypre_Index dist )
210 {
211 hypre_CopyIndex(dist, hypre_StructGridMaxDistance(grid));
212
213 return hypre_error_flag;
214 }
215
216 /*--------------------------------------------------------------------------
217 * New - hypre_StructGridAssemble
218 * AHB 9/06
219 * New assemble routine that uses the BoxManager structure
220 *
221 * Notes:
222 * 1. No longer need a different assemble for the assumed partition case
223 * 2. if this is called from StructCoarsen, then the Box Manager has already
224 * been created, and ids have been set
225 *
226 *--------------------------------------------------------------------------*/
227
228 HYPRE_Int
hypre_StructGridAssemble(hypre_StructGrid * grid)229 hypre_StructGridAssemble( hypre_StructGrid *grid )
230 {
231
232 HYPRE_Int d, k, p, i;
233
234 HYPRE_Int is_boxman;
235 HYPRE_Int size, ghostsize;
236 HYPRE_Int num_local_boxes;
237 HYPRE_Int myid, num_procs;
238 HYPRE_BigInt global_size;
239 HYPRE_Int max_nentries;
240 HYPRE_Int info_size;
241 HYPRE_Int num_periods;
242
243 HYPRE_Int *ids = NULL;
244 HYPRE_Int iperiodic, notcenter;
245
246 HYPRE_Int sendbuf6[2*HYPRE_MAXDIM], recvbuf6[2*HYPRE_MAXDIM];
247
248 hypre_Box *box;
249 hypre_Box *ghostbox;
250 hypre_Box *grow_box;
251 hypre_Box *periodic_box;
252 hypre_Box *result_box;
253
254 hypre_Index min_index, max_index, loop_size;
255 hypre_Index *pshifts;
256 hypre_IndexRef pshift;
257
258 void *entry_info = NULL;
259
260 /* initialize info from the grid */
261 MPI_Comm comm = hypre_StructGridComm(grid);
262 HYPRE_Int ndim = hypre_StructGridNDim(grid);
263 hypre_BoxArray *local_boxes = hypre_StructGridBoxes(grid);
264 hypre_IndexRef max_distance = hypre_StructGridMaxDistance(grid);
265 hypre_Box *bounding_box = hypre_StructGridBoundingBox(grid);
266 hypre_IndexRef periodic = hypre_StructGridPeriodic(grid);
267 hypre_BoxManager *boxman = hypre_StructGridBoxMan(grid);
268 HYPRE_Int *numghost = hypre_StructGridNumGhost(grid);
269
270 if (!time_index)
271 time_index = hypre_InitializeTiming("StructGridAssemble");
272
273 hypre_BeginTiming(time_index);
274
275 /* other initializations */
276 num_local_boxes = hypre_BoxArraySize(local_boxes);
277
278 hypre_MPI_Comm_size(comm, &num_procs);
279 hypre_MPI_Comm_rank(comm, &myid);
280
281 /* has the box manager been created? */
282 if (boxman == NULL)
283 {
284 is_boxman = 0;
285 }
286 else
287 {
288 is_boxman = 1;
289 }
290
291 /* are the ids known? (these may have been set in coarsen) - if not we need
292 to set them */
293 if (hypre_StructGridIDs(grid) == NULL)
294 {
295 ids = hypre_CTAlloc(HYPRE_Int, num_local_boxes, HYPRE_MEMORY_HOST);
296 for (i=0; i< num_local_boxes; i++)
297 {
298 ids[i] = i;
299 }
300 hypre_StructGridIDs(grid) = ids;
301 }
302 else
303 {
304 ids = hypre_StructGridIDs(grid);
305 }
306
307 /******** calculate the periodicity information ****************/
308
309 box = hypre_BoxCreate(ndim);
310 for (d = 0; d < ndim; d++)
311 {
312 iperiodic = hypre_IndexD(periodic, d) ? 1 : 0;
313 hypre_BoxIMinD(box, d) = -iperiodic;
314 hypre_BoxIMaxD(box, d) = iperiodic;
315 }
316 num_periods = hypre_BoxVolume(box);
317
318 pshifts = hypre_CTAlloc(hypre_Index, num_periods, HYPRE_MEMORY_HOST);
319 pshift = pshifts[0];
320 hypre_SetIndex(pshift, 0);
321 if (num_periods > 1)
322 {
323 p = 1;
324 hypre_BoxGetSize(box, loop_size);
325 hypre_SerialBoxLoop0Begin(ndim, loop_size);
326 {
327 pshift = pshifts[p];
328 zypre_BoxLoopGetIndex(pshift);
329 hypre_AddIndexes(pshift, hypre_BoxIMin(box), ndim, pshift);
330 notcenter = 0;
331 for (d = 0; d < ndim; d++)
332 {
333 hypre_IndexD(pshift, d) *= hypre_IndexD(periodic, d);
334 if (hypre_IndexD(pshift, d))
335 {
336 notcenter = 1;
337 }
338 }
339 if (notcenter)
340 {
341 p++;
342 }
343 }
344 hypre_SerialBoxLoop0End();
345 }
346 hypre_BoxDestroy(box);
347
348 hypre_StructGridNumPeriods(grid) = num_periods;
349 hypre_StructGridPShifts(grid) = pshifts;
350
351 /********calculate local size and the ghost size **************/
352
353 size = 0;
354 ghostsize = 0;
355 ghostbox = hypre_BoxCreate(ndim);
356
357 hypre_ForBoxI(i, local_boxes)
358 {
359 box = hypre_BoxArrayBox(local_boxes, i);
360 size += hypre_BoxVolume(box);
361
362 hypre_CopyBox(box, ghostbox);
363 hypre_BoxGrowByArray(ghostbox, numghost);
364 ghostsize += hypre_BoxVolume(ghostbox);
365 }
366
367 hypre_StructGridLocalSize(grid) = size;
368 hypre_StructGridGhlocalSize(grid) = ghostsize;
369 hypre_BoxDestroy(ghostbox);
370
371 /* if the box manager has been created then we don't need to do the
372 * following (because it was done through the coarsening routine) */
373 if (!is_boxman)
374 {
375 /*************** set the global size *****************/
376
377 HYPRE_BigInt big_size = (HYPRE_BigInt)size;
378 hypre_MPI_Allreduce(&big_size, &global_size, 1, HYPRE_MPI_BIG_INT,
379 hypre_MPI_SUM, comm);
380 hypre_StructGridGlobalSize(grid) = global_size; /* TO DO: this HYPRE_Int
381 * could overflow! (used
382 * to calc flops) */
383
384 /*************** set bounding box ***********/
385
386 bounding_box = hypre_BoxCreate(ndim);
387
388 if (num_local_boxes)
389 {
390 /* initialize min and max index*/
391 box = hypre_BoxArrayBox(local_boxes, 0);
392 for (d = 0; d < ndim; d++)
393 {
394 hypre_IndexD(min_index, d) = hypre_BoxIMinD(box, d);
395 hypre_IndexD(max_index, d) = hypre_BoxIMaxD(box, d);
396 }
397
398 hypre_ForBoxI(i, local_boxes)
399 {
400 box = hypre_BoxArrayBox(local_boxes, i);
401
402
403 /* find min and max box extents */
404 for (d = 0; d < ndim; d++)
405 {
406 hypre_IndexD(min_index, d) = hypre_min( hypre_IndexD(min_index, d),
407 hypre_BoxIMinD(box, d));
408 hypre_IndexD(max_index, d) = hypre_max( hypre_IndexD(max_index, d),
409 hypre_BoxIMaxD(box, d));
410 }
411 }
412 /*set bounding box (this is still based on local info only) */
413 hypre_BoxSetExtents(bounding_box, min_index, max_index);
414
415 }
416 else /* no boxes owned*/
417 {
418 /* initialize min and max */
419 for (d = 0; d < ndim; d++)
420 {
421 hypre_BoxIMinD(bounding_box, d) = hypre_pow2(30);
422 hypre_BoxIMaxD(bounding_box, d) = -hypre_pow2(30);
423 }
424 }
425 /* set the extra dimensions of the bounding box to zero */
426 for (d = ndim; d < HYPRE_MAXDIM; d++)
427 {
428 hypre_BoxIMinD(bounding_box, d) = 0;
429 hypre_BoxIMaxD(bounding_box, d) = 0;
430 }
431
432 /* communication needed for the bounding box */
433 /* pack buffer */
434 for (d = 0; d < ndim; d++)
435 {
436 sendbuf6[d] = hypre_BoxIMinD(bounding_box, d);
437 sendbuf6[d+ndim] = -hypre_BoxIMaxD(bounding_box, d);
438 }
439 hypre_MPI_Allreduce(sendbuf6, recvbuf6, 2*ndim, HYPRE_MPI_INT,
440 hypre_MPI_MIN, comm);
441 /* unpack buffer */
442 for (d = 0; d < ndim; d++)
443 {
444 hypre_BoxIMinD(bounding_box, d) = recvbuf6[d];
445 hypre_BoxIMaxD(bounding_box, d) = -recvbuf6[d+ndim];
446 }
447
448 hypre_StructGridBoundingBox(grid) = bounding_box;
449
450 /*************** create a box manager *****************/
451 max_nentries = num_local_boxes + 20;
452 info_size = 0; /* we don't need an info object */
453 hypre_BoxManCreate(max_nentries, info_size, ndim, bounding_box,
454 comm, &boxman);
455
456 /******** populate the box manager with my local boxes and gather neighbor
457 information ******/
458
459 grow_box = hypre_BoxCreate(ndim);
460 result_box = hypre_BoxCreate(ndim);
461 periodic_box = hypre_BoxCreate(ndim);
462
463 /* now loop through each local box */
464 hypre_ForBoxI(i, local_boxes)
465 {
466 box = hypre_BoxArrayBox(local_boxes, i);
467 /* add entry for each local box (the id is the boxnum, and should be
468 sequential */
469 hypre_BoxManAddEntry( boxman, hypre_BoxIMin(box), hypre_BoxIMax(box),
470 myid, i, entry_info );
471
472 /* now expand box by max_distance or larger and gather entries */
473 hypre_CopyBox(box ,grow_box);
474 hypre_BoxGrowByIndex(grow_box, max_distance);
475 hypre_BoxManGatherEntries(boxman, hypre_BoxIMin(grow_box),
476 hypre_BoxIMax(grow_box));
477
478 /* now repeat for any periodic boxes - by shifting the grow_box*/
479 for (k=1; k < num_periods; k++) /* k=0 is original box */
480 {
481 hypre_CopyBox(grow_box, periodic_box);
482 pshift = pshifts[k];
483 hypre_BoxShiftPos(periodic_box, pshift);
484
485 /* see if the shifted box intersects the domain */
486 hypre_IntersectBoxes(periodic_box, bounding_box, result_box);
487 /* if so, call gather entries */
488 if (hypre_BoxVolume(result_box) > 0)
489 {
490 hypre_BoxManGatherEntries(boxman, hypre_BoxIMin(periodic_box),
491 hypre_BoxIMax(periodic_box));
492 }
493 }
494 }/* end of for each local box */
495
496 hypre_BoxDestroy(periodic_box);
497 hypre_BoxDestroy(grow_box);
498 hypre_BoxDestroy(result_box);
499
500 } /* end of if (!is_boxman) */
501
502 /* boxman was created, but need to get additional neighbor info */
503 else if ( hypre_IndexEqual(max_distance, 0, ndim) )
504 {
505 /* pick a new max distance and set in grid*/
506 hypre_SetIndex(hypre_StructGridMaxDistance(grid), 2);
507 max_distance = hypre_StructGridMaxDistance(grid);
508
509 grow_box = hypre_BoxCreate(ndim);
510 result_box = hypre_BoxCreate(ndim);
511 periodic_box = hypre_BoxCreate(ndim);
512
513 /* now loop through each local box */
514 hypre_ForBoxI(i, local_boxes)
515 {
516 box = hypre_BoxArrayBox(local_boxes, i);
517
518 /* now expand box by max_distance or larger and gather entries */
519 hypre_CopyBox(box ,grow_box);
520 hypre_BoxGrowByIndex(grow_box, max_distance);
521 hypre_BoxManGatherEntries(boxman, hypre_BoxIMin(grow_box),
522 hypre_BoxIMax(grow_box));
523
524 /* now repeat for any periodic boxes - by shifting the grow_box*/
525 for (k=1; k < num_periods; k++) /* k=0 is original box */
526 {
527 hypre_CopyBox(grow_box, periodic_box);
528 pshift = pshifts[k];
529 hypre_BoxShiftPos(periodic_box, pshift);
530
531 /* see if the shifted box intersects the domain */
532 hypre_IntersectBoxes(periodic_box, bounding_box, result_box);
533 /* if so, call gather entries */
534 if (hypre_BoxVolume(result_box) > 0)
535 {
536 hypre_BoxManGatherEntries(boxman, hypre_BoxIMin(periodic_box),
537 hypre_BoxIMax(periodic_box));
538 }
539 }
540 }/* end of for each local box */
541
542 hypre_BoxDestroy(periodic_box);
543 hypre_BoxDestroy(grow_box);
544 hypre_BoxDestroy(result_box);
545 }
546
547 /***************Assemble the box manager *****************/
548
549 hypre_BoxManAssemble(boxman);
550
551 hypre_StructGridBoxMan(grid) = boxman;
552
553 hypre_EndTiming(time_index);
554
555 return hypre_error_flag;
556 }
557
558 /*--------------------------------------------------------------------------
559 * hypre_GatherAllBoxes
560 *--------------------------------------------------------------------------*/
561
562 HYPRE_Int
hypre_GatherAllBoxes(MPI_Comm comm,hypre_BoxArray * boxes,HYPRE_Int ndim,hypre_BoxArray ** all_boxes_ptr,HYPRE_Int ** all_procs_ptr,HYPRE_Int * first_local_ptr)563 hypre_GatherAllBoxes(MPI_Comm comm,
564 hypre_BoxArray *boxes,
565 HYPRE_Int ndim,
566 hypre_BoxArray **all_boxes_ptr,
567 HYPRE_Int **all_procs_ptr,
568 HYPRE_Int *first_local_ptr)
569 {
570 hypre_BoxArray *all_boxes;
571 HYPRE_Int *all_procs;
572 HYPRE_Int first_local;
573 HYPRE_Int all_boxes_size;
574
575 hypre_Box *box;
576 hypre_Index imin;
577 hypre_Index imax;
578
579 HYPRE_Int num_all_procs, my_rank;
580
581 HYPRE_Int *sendbuf;
582 HYPRE_Int sendcount;
583 HYPRE_Int *recvbuf;
584 HYPRE_Int *recvcounts;
585 HYPRE_Int *displs;
586 HYPRE_Int recvbuf_size;
587 HYPRE_Int item_size;
588
589 HYPRE_Int i, p, b, d;
590
591 /*-----------------------------------------------------
592 * Accumulate the box info
593 *-----------------------------------------------------*/
594
595 hypre_MPI_Comm_size(comm, &num_all_procs);
596 hypre_MPI_Comm_rank(comm, &my_rank);
597
598 /* compute recvcounts and displs */
599 item_size = 2*ndim + 1;
600 sendcount = item_size*hypre_BoxArraySize(boxes);
601 recvcounts = hypre_TAlloc(HYPRE_Int, num_all_procs, HYPRE_MEMORY_HOST);
602 displs = hypre_TAlloc(HYPRE_Int, num_all_procs, HYPRE_MEMORY_HOST);
603 hypre_MPI_Allgather(&sendcount, 1, HYPRE_MPI_INT,
604 recvcounts, 1, HYPRE_MPI_INT, comm);
605 displs[0] = 0;
606 recvbuf_size = recvcounts[0];
607 for (p = 1; p < num_all_procs; p++)
608 {
609 displs[p] = displs[p-1] + recvcounts[p-1];
610 recvbuf_size += recvcounts[p];
611 }
612
613 /* allocate sendbuf and recvbuf */
614 sendbuf = hypre_TAlloc(HYPRE_Int, sendcount, HYPRE_MEMORY_HOST);
615 recvbuf = hypre_TAlloc(HYPRE_Int, recvbuf_size, HYPRE_MEMORY_HOST);
616
617 /* put local box extents and process number into sendbuf */
618 i = 0;
619 for (b = 0; b < hypre_BoxArraySize(boxes); b++)
620 {
621 sendbuf[i++] = my_rank;
622
623 box = hypre_BoxArrayBox(boxes, b);
624 for (d = 0; d < ndim; d++)
625 {
626 sendbuf[i++] = hypre_BoxIMinD(box, d);
627 sendbuf[i++] = hypre_BoxIMaxD(box, d);
628 }
629 }
630
631 /* get global grid info */
632 hypre_MPI_Allgatherv(sendbuf, sendcount, HYPRE_MPI_INT,
633 recvbuf, recvcounts, displs, HYPRE_MPI_INT, comm);
634
635 /* sort recvbuf by process rank? */
636
637 /*-----------------------------------------------------
638 * Create all_boxes, etc.
639 *-----------------------------------------------------*/
640
641 /* unpack recvbuf box info */
642 all_boxes_size = recvbuf_size / item_size;
643 all_boxes = hypre_BoxArrayCreate(all_boxes_size, ndim);
644 all_procs = hypre_TAlloc(HYPRE_Int, all_boxes_size, HYPRE_MEMORY_HOST);
645 first_local = -1;
646 i = 0;
647 b = 0;
648 box = hypre_BoxCreate(ndim);
649 while (i < recvbuf_size)
650 {
651 all_procs[b] = recvbuf[i++];
652 for (d = 0; d < ndim; d++)
653 {
654 hypre_IndexD(imin, d) = recvbuf[i++];
655 hypre_IndexD(imax, d) = recvbuf[i++];
656 }
657 hypre_BoxSetExtents(box, imin, imax);
658 hypre_CopyBox(box, hypre_BoxArrayBox(all_boxes, b));
659
660 if ((first_local < 0) && (all_procs[b] == my_rank))
661 {
662 first_local = b;
663 }
664
665 b++;
666 }
667 hypre_BoxDestroy(box);
668
669 /*-----------------------------------------------------
670 * Return
671 *-----------------------------------------------------*/
672
673 hypre_TFree(sendbuf, HYPRE_MEMORY_HOST);
674 hypre_TFree(recvbuf, HYPRE_MEMORY_HOST);
675 hypre_TFree(recvcounts, HYPRE_MEMORY_HOST);
676 hypre_TFree(displs, HYPRE_MEMORY_HOST);
677
678 *all_boxes_ptr = all_boxes;
679 *all_procs_ptr = all_procs;
680 *first_local_ptr = first_local;
681
682 return hypre_error_flag;
683 }
684
685 /*--------------------------------------------------------------------------
686 * hypre_ComputeBoxnums
687 *
688 * It is assumed that, for any process number in 'procs', all of that
689 * processes local boxes appear in the 'boxes' array.
690 *
691 * It is assumed that the boxes in 'boxes' are ordered by associated
692 * process number then by their local ordering on that process.
693 *
694 *--------------------------------------------------------------------------*/
695
696 HYPRE_Int
hypre_ComputeBoxnums(hypre_BoxArray * boxes,HYPRE_Int * procs,HYPRE_Int ** boxnums_ptr)697 hypre_ComputeBoxnums(hypre_BoxArray *boxes,
698 HYPRE_Int *procs,
699 HYPRE_Int **boxnums_ptr)
700 {
701
702 HYPRE_Int *boxnums;
703 HYPRE_Int num_boxes;
704 HYPRE_Int p, b, boxnum;
705
706 /*-----------------------------------------------------
707 *-----------------------------------------------------*/
708
709 num_boxes = hypre_BoxArraySize(boxes);
710 boxnums = hypre_TAlloc(HYPRE_Int, num_boxes, HYPRE_MEMORY_HOST);
711
712 p = -1;
713 for(b = 0; b < num_boxes; b++)
714 {
715 /* start boxnum count at zero for each new process */
716 if (procs[b] != p)
717 {
718 boxnum = 0;
719 p = procs[b];
720 }
721 boxnums[b] = boxnum;
722 boxnum++;
723 }
724
725 *boxnums_ptr = boxnums;
726
727 return hypre_error_flag;
728 }
729
730 /*--------------------------------------------------------------------------
731 * hypre_StructGridPrint
732 *--------------------------------------------------------------------------*/
733
734 HYPRE_Int
hypre_StructGridPrint(FILE * file,hypre_StructGrid * grid)735 hypre_StructGridPrint( FILE *file,
736 hypre_StructGrid *grid )
737 {
738
739 hypre_BoxArray *boxes;
740 hypre_Box *box;
741
742 HYPRE_Int i, d, ndim;
743
744 ndim = hypre_StructGridNDim(grid);
745 hypre_fprintf(file, "%d\n", ndim);
746
747 boxes = hypre_StructGridBoxes(grid);
748 hypre_fprintf(file, "%d\n", hypre_BoxArraySize(boxes));
749
750 /* Print lines of the form: "%d: (%d, %d, %d) x (%d, %d, %d)\n" */
751 hypre_ForBoxI(i, boxes)
752 {
753 box = hypre_BoxArrayBox(boxes, i);
754 hypre_fprintf(file, "%d: (%d", i, hypre_BoxIMinD(box, 0));
755 for (d = 1; d < ndim; d++)
756 {
757 hypre_fprintf(file, ", %d", hypre_BoxIMinD(box, d));
758 }
759 hypre_fprintf(file, ") x (%d", hypre_BoxIMaxD(box, 0));
760 for (d = 1; d < ndim; d++)
761 {
762 hypre_fprintf(file, ", %d", hypre_BoxIMaxD(box, d));
763 }
764 hypre_fprintf(file, ")\n");
765 }
766 /* Print line of the form: "Periodic: %d %d %d\n" */
767 hypre_fprintf(file, "\nPeriodic:");
768 for (d = 0; d < ndim; d++)
769 {
770 hypre_fprintf(file, " %d", hypre_StructGridPeriodic(grid)[d]);
771 }
772 hypre_fprintf(file, "\n");
773
774 return hypre_error_flag;
775 }
776
777 /*--------------------------------------------------------------------------
778 * hypre_StructGridRead
779 *--------------------------------------------------------------------------*/
780
781 HYPRE_Int
hypre_StructGridRead(MPI_Comm comm,FILE * file,hypre_StructGrid ** grid_ptr)782 hypre_StructGridRead( MPI_Comm comm,
783 FILE *file,
784 hypre_StructGrid **grid_ptr )
785 {
786
787 hypre_StructGrid *grid;
788
789 hypre_Index ilower;
790 hypre_Index iupper;
791 hypre_IndexRef periodic;
792
793 HYPRE_Int ndim;
794 HYPRE_Int num_boxes;
795
796 HYPRE_Int i, d, idummy;
797
798 hypre_fscanf(file, "%d\n", &ndim);
799 hypre_StructGridCreate(comm, ndim, &grid);
800
801 hypre_fscanf(file, "%d\n", &num_boxes);
802
803 /* Read lines of the form: "%d: (%d, %d, %d) x (%d, %d, %d)\n" */
804 for (i = 0; i < num_boxes; i++)
805 {
806 hypre_fscanf(file, "%d: (%d", &idummy, &hypre_IndexD(ilower, 0));
807 for (d = 1; d < ndim; d++)
808 {
809 hypre_fscanf(file, ", %d", &hypre_IndexD(ilower, d));
810 }
811 hypre_fscanf(file, ") x (%d", &hypre_IndexD(iupper, 0));
812 for (d = 1; d < ndim; d++)
813 {
814 hypre_fscanf(file, ", %d", &hypre_IndexD(iupper, d));
815 }
816 hypre_fscanf(file, ")\n");
817
818 hypre_StructGridSetExtents(grid, ilower, iupper);
819 }
820
821 periodic = hypre_StructGridPeriodic(grid);
822
823 /* Read line of the form: "Periodic: %d %d %d\n" */
824 hypre_fscanf(file, "Periodic:");
825 for (d = 0; d < ndim; d++)
826 {
827 hypre_fscanf(file, " %d", &hypre_IndexD(periodic, d));
828 }
829 hypre_fscanf(file, "\n");
830
831 hypre_StructGridAssemble(grid);
832
833 *grid_ptr = grid;
834
835 return hypre_error_flag;
836 }
837
838 /*------------------------------------------------------------------------------
839 * GEC0902 hypre_StructGridSetNumGhost
840 *
841 * the purpose is to set num ghost in the structure grid. It is identical
842 * to the function that is used in the structure vector entity.
843 *-----------------------------------------------------------------------------*/
844
845 HYPRE_Int
hypre_StructGridSetNumGhost(hypre_StructGrid * grid,HYPRE_Int * num_ghost)846 hypre_StructGridSetNumGhost( hypre_StructGrid *grid, HYPRE_Int *num_ghost )
847 {
848 HYPRE_Int i, ndim = hypre_StructGridNDim(grid);
849
850 for (i = 0; i < 2*ndim; i++)
851 {
852 hypre_StructGridNumGhost(grid)[i] = num_ghost[i];
853 }
854
855 return hypre_error_flag;
856 }
857
858
859 #if 0 //defined(HYPRE_USING_CUDA) || defined(HYPRE_USING_HIP)
860 HYPRE_Int
861 hypre_StructGridGetMaxBoxSize(hypre_StructGrid *grid)
862 {
863 hypre_Box *box;
864 hypre_BoxArray *boxes;
865 HYPRE_Int box_size;
866 HYPRE_Int i;
867 HYPRE_Int max_box_size = 0;
868 boxes = hypre_StructGridBoxes(grid);
869 hypre_ForBoxI(i, boxes)
870 {
871 box = hypre_BoxArrayBox(hypre_StructGridBoxes(grid), i);
872 box_size = hypre_BoxVolume(box);
873 if (box_size > max_box_size)
874 {
875 max_box_size = box_size;
876 }
877 }
878 return max_box_size;
879 }
880
881 HYPRE_Int
882 hypre_StructGridSetDataLocation( HYPRE_StructGrid grid, HYPRE_MemoryLocation data_location )
883 {
884 hypre_StructGridDataLocation(grid) = data_location;
885
886 return hypre_error_flag;
887 }
888
889 #endif
890