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_Box class:
11  *   Basic class functions.
12  *
13  *****************************************************************************/
14 
15 #include "_hypre_struct_mv.h"
16 
17 /*==========================================================================
18  * Member functions: hypre_Index
19  *==========================================================================*/
20 
21 /*--------------------------------------------------------------------------
22  *--------------------------------------------------------------------------*/
23 
24 HYPRE_Int
hypre_SetIndex(hypre_Index index,HYPRE_Int val)25 hypre_SetIndex( hypre_Index  index,
26                 HYPRE_Int    val )
27 {
28    HYPRE_Int d;
29 
30    for (d = 0; d < HYPRE_MAXDIM; d++)
31    {
32       hypre_IndexD(index, d) = val;
33    }
34 
35    return hypre_error_flag;
36 }
37 
38 /*--------------------------------------------------------------------------
39  *--------------------------------------------------------------------------*/
40 
41 HYPRE_Int
hypre_CopyIndex(hypre_Index in_index,hypre_Index out_index)42 hypre_CopyIndex( hypre_Index  in_index,
43                  hypre_Index  out_index )
44 {
45    HYPRE_Int d;
46 
47    for (d = 0; d < HYPRE_MAXDIM; d++)
48    {
49       hypre_IndexD(out_index, d) = hypre_IndexD(in_index, d);
50    }
51 
52    return hypre_error_flag;
53 }
54 
55 /*--------------------------------------------------------------------------
56  *--------------------------------------------------------------------------*/
57 
58 HYPRE_Int
hypre_CopyToCleanIndex(hypre_Index in_index,HYPRE_Int ndim,hypre_Index out_index)59 hypre_CopyToCleanIndex( hypre_Index  in_index,
60                         HYPRE_Int    ndim,
61                         hypre_Index  out_index )
62 {
63    HYPRE_Int d;
64    for (d = 0; d < ndim; d++)
65    {
66       hypre_IndexD(out_index, d) = hypre_IndexD(in_index, d);
67    }
68    for (d = ndim; d < HYPRE_MAXDIM; d++)
69    {
70       hypre_IndexD(out_index, d) = 0;
71    }
72 
73    return hypre_error_flag;
74 }
75 
76 /*--------------------------------------------------------------------------
77  *--------------------------------------------------------------------------*/
78 
79 HYPRE_Int
hypre_IndexEqual(hypre_Index index,HYPRE_Int val,HYPRE_Int ndim)80 hypre_IndexEqual( hypre_Index  index,
81                   HYPRE_Int    val,
82                   HYPRE_Int    ndim )
83 {
84    HYPRE_Int d, equal;
85 
86    equal = 1;
87    for (d = 0; d < ndim; d++)
88    {
89       if (hypre_IndexD(index, d) != val)
90       {
91          equal = 0;
92          break;
93       }
94    }
95 
96    return equal;
97 }
98 
99 /*--------------------------------------------------------------------------
100  *--------------------------------------------------------------------------*/
101 
102 HYPRE_Int
hypre_IndexMin(hypre_Index index,HYPRE_Int ndim)103 hypre_IndexMin( hypre_Index  index,
104                 HYPRE_Int    ndim )
105 {
106    HYPRE_Int d, min;
107 
108    min = hypre_IndexD(index, 0);
109    for (d = 1; d < ndim; d++)
110    {
111       if (hypre_IndexD(index, d) < min)
112       {
113          min = hypre_IndexD(index, d);
114       }
115    }
116 
117    return min;
118 }
119 
120 /*--------------------------------------------------------------------------
121  *--------------------------------------------------------------------------*/
122 
123 HYPRE_Int
hypre_IndexMax(hypre_Index index,HYPRE_Int ndim)124 hypre_IndexMax( hypre_Index  index,
125                 HYPRE_Int    ndim )
126 {
127    HYPRE_Int d, max;
128 
129    max = hypre_IndexD(index, 0);
130    for (d = 1; d < ndim; d++)
131    {
132       if (hypre_IndexD(index, d) < max)
133       {
134          max = hypre_IndexD(index, d);
135       }
136    }
137 
138    return max;
139 }
140 
141 /*--------------------------------------------------------------------------
142  *--------------------------------------------------------------------------*/
143 
144 HYPRE_Int
hypre_AddIndexes(hypre_Index index1,hypre_Index index2,HYPRE_Int ndim,hypre_Index result)145 hypre_AddIndexes( hypre_Index  index1,
146                   hypre_Index  index2,
147                   HYPRE_Int    ndim,
148                   hypre_Index  result )
149 {
150    HYPRE_Int d;
151 
152    for (d = 0; d < ndim; d++)
153    {
154       hypre_IndexD(result, d) = hypre_IndexD(index1, d) + hypre_IndexD(index2, d);
155    }
156 
157    return hypre_error_flag;
158 }
159 
160 /*--------------------------------------------------------------------------
161  *--------------------------------------------------------------------------*/
162 
163 HYPRE_Int
hypre_SubtractIndexes(hypre_Index index1,hypre_Index index2,HYPRE_Int ndim,hypre_Index result)164 hypre_SubtractIndexes( hypre_Index  index1,
165                        hypre_Index  index2,
166                        HYPRE_Int    ndim,
167                        hypre_Index  result )
168 {
169    HYPRE_Int d;
170 
171    for (d = 0; d < ndim; d++)
172    {
173       hypre_IndexD(result, d) = hypre_IndexD(index1, d) - hypre_IndexD(index2, d);
174    }
175 
176    return hypre_error_flag;
177 }
178 
179 /*--------------------------------------------------------------------------
180  *--------------------------------------------------------------------------*/
181 
182 HYPRE_Int
hypre_IndexesEqual(hypre_Index index1,hypre_Index index2,HYPRE_Int ndim)183 hypre_IndexesEqual( hypre_Index  index1,
184                     hypre_Index  index2,
185                     HYPRE_Int    ndim )
186 {
187    HYPRE_Int d, equal;
188 
189    equal = 1;
190    for (d = 0; d < ndim; d++)
191    {
192       if (hypre_IndexD(index1, d) != hypre_IndexD(index2, d))
193       {
194          equal = 0;
195          break;
196       }
197    }
198 
199    return equal;
200 }
201 
202 /*==========================================================================
203  * Member functions: hypre_Box
204  *==========================================================================*/
205 
206 /*--------------------------------------------------------------------------
207  *--------------------------------------------------------------------------*/
208 
209 hypre_Box *
hypre_BoxCreate(HYPRE_Int ndim)210 hypre_BoxCreate( HYPRE_Int  ndim )
211 {
212    hypre_Box *box;
213 
214    box = hypre_CTAlloc(hypre_Box,  1, HYPRE_MEMORY_HOST);
215    hypre_BoxNDim(box) = ndim;
216 
217    return box;
218 }
219 
220 /*--------------------------------------------------------------------------
221  *--------------------------------------------------------------------------*/
222 
223 HYPRE_Int
hypre_BoxDestroy(hypre_Box * box)224 hypre_BoxDestroy( hypre_Box *box )
225 {
226    if (box)
227    {
228       hypre_TFree(box, HYPRE_MEMORY_HOST);
229    }
230 
231    return hypre_error_flag;
232 }
233 
234 /*--------------------------------------------------------------------------
235  * This is used to initialize ndim when the box has static storage
236  *--------------------------------------------------------------------------*/
237 
238 HYPRE_Int
hypre_BoxInit(hypre_Box * box,HYPRE_Int ndim)239 hypre_BoxInit( hypre_Box *box,
240                HYPRE_Int  ndim )
241 {
242    hypre_BoxNDim(box) = ndim;
243 
244    return hypre_error_flag;
245 }
246 
247 /*--------------------------------------------------------------------------
248  *--------------------------------------------------------------------------*/
249 
250 HYPRE_Int
hypre_BoxSetExtents(hypre_Box * box,hypre_Index imin,hypre_Index imax)251 hypre_BoxSetExtents( hypre_Box  *box,
252                      hypre_Index imin,
253                      hypre_Index imax )
254 {
255    hypre_CopyIndex(imin, hypre_BoxIMin(box));
256    hypre_CopyIndex(imax, hypre_BoxIMax(box));
257 
258    return hypre_error_flag;
259 }
260 
261 /*--------------------------------------------------------------------------
262  *--------------------------------------------------------------------------*/
263 
264 HYPRE_Int
hypre_CopyBox(hypre_Box * box1,hypre_Box * box2)265 hypre_CopyBox( hypre_Box  *box1,
266                hypre_Box  *box2 )
267 {
268    hypre_CopyIndex(hypre_BoxIMin(box1), hypre_BoxIMin(box2));
269    hypre_CopyIndex(hypre_BoxIMax(box1), hypre_BoxIMax(box2));
270    hypre_BoxNDim(box2) = hypre_BoxNDim(box1);
271 
272    return hypre_error_flag;
273 }
274 
275 /*--------------------------------------------------------------------------
276  * Return a duplicate box.
277  *--------------------------------------------------------------------------*/
278 
279 hypre_Box *
hypre_BoxDuplicate(hypre_Box * box)280 hypre_BoxDuplicate( hypre_Box *box )
281 {
282    hypre_Box  *new_box;
283 
284    new_box = hypre_BoxCreate(hypre_BoxNDim(box));
285    hypre_CopyBox(box, new_box);
286 
287    return new_box;
288 }
289 
290 /*--------------------------------------------------------------------------
291  *--------------------------------------------------------------------------*/
292 
293 HYPRE_Int
hypre_BoxVolume(hypre_Box * box)294 hypre_BoxVolume( hypre_Box *box )
295 {
296    HYPRE_Int volume, d, ndim = hypre_BoxNDim(box);
297 
298    volume = 1;
299    for (d = 0; d < ndim; d++)
300    {
301       volume *= hypre_BoxSizeD(box, d);
302    }
303 
304    return volume;
305 }
306 
307 /*--------------------------------------------------------------------------
308  * To prevent overflow when needed
309  *--------------------------------------------------------------------------*/
310 
311 HYPRE_Real
hypre_doubleBoxVolume(hypre_Box * box)312 hypre_doubleBoxVolume( hypre_Box *box )
313 {
314    HYPRE_Real    volume;
315    HYPRE_Int d, ndim = hypre_BoxNDim(box);
316 
317    volume = 1.0;
318    for (d = 0; d < ndim; d++)
319    {
320       volume *= hypre_BoxSizeD(box, d);
321    }
322 
323    return volume;
324 }
325 
326 /*--------------------------------------------------------------------------
327  *--------------------------------------------------------------------------*/
328 
329 HYPRE_Int
hypre_IndexInBox(hypre_Index index,hypre_Box * box)330 hypre_IndexInBox( hypre_Index   index,
331                   hypre_Box    *box )
332 {
333    HYPRE_Int d, inbox, ndim = hypre_BoxNDim(box);
334 
335    inbox = 1;
336    for (d = 0; d < ndim; d++)
337    {
338       if (!hypre_IndexDInBox(index, d, box))
339       {
340          inbox = 0;
341          break;
342       }
343    }
344 
345    return inbox;
346 }
347 
348 /*--------------------------------------------------------------------------
349  *--------------------------------------------------------------------------*/
350 
351 HYPRE_Int
hypre_BoxGetSize(hypre_Box * box,hypre_Index size)352 hypre_BoxGetSize( hypre_Box   *box,
353                   hypre_Index  size )
354 {
355    HYPRE_Int d, ndim = hypre_BoxNDim(box);
356 
357    for (d = 0; d < ndim; d++)
358    {
359       hypre_IndexD(size, d) = hypre_BoxSizeD(box, d);
360    }
361 
362    return hypre_error_flag;
363 }
364 
365 /*--------------------------------------------------------------------------
366  *--------------------------------------------------------------------------*/
367 
368 HYPRE_Int
hypre_BoxGetStrideSize(hypre_Box * box,hypre_Index stride,hypre_Index size)369 hypre_BoxGetStrideSize( hypre_Box   *box,
370                         hypre_Index  stride,
371                         hypre_Index  size   )
372 {
373    HYPRE_Int  d, s, ndim = hypre_BoxNDim(box);
374 
375    for (d = 0; d < ndim; d++)
376    {
377       s = hypre_BoxSizeD(box, d);
378       if (s > 0)
379       {
380          s = (s - 1) / hypre_IndexD(stride, d) + 1;
381       }
382       hypre_IndexD(size, d) = s;
383    }
384 
385    return hypre_error_flag;
386 }
387 
388 /*--------------------------------------------------------------------------
389  *--------------------------------------------------------------------------*/
390 
391 HYPRE_Int
hypre_BoxGetStrideVolume(hypre_Box * box,hypre_Index stride,HYPRE_Int * volume_ptr)392 hypre_BoxGetStrideVolume( hypre_Box   *box,
393                           hypre_Index  stride,
394                           HYPRE_Int   *volume_ptr )
395 {
396    HYPRE_Int  volume, d, s, ndim = hypre_BoxNDim(box);
397 
398    volume = 1;
399    for (d = 0; d < ndim; d++)
400    {
401       s = hypre_BoxSizeD(box, d);
402       if (s > 0)
403       {
404          s = (s - 1) / hypre_IndexD(stride, d) + 1;
405       }
406       volume *= s;
407    }
408 
409    *volume_ptr = volume;
410 
411    return hypre_error_flag;
412 }
413 
414 /*--------------------------------------------------------------------------
415  * Returns the rank of an index into a multi-D box where the assumed ordering is
416  * dimension 0 first, then dimension 1, etc.
417  *--------------------------------------------------------------------------*/
418 
419 HYPRE_Int
hypre_BoxIndexRank(hypre_Box * box,hypre_Index index)420 hypre_BoxIndexRank( hypre_Box   *box,
421                     hypre_Index  index )
422 {
423    HYPRE_Int  rank, size, d, ndim = hypre_BoxNDim(box);
424 
425    rank = 0;
426    size = 1;
427    for (d = 0; d < ndim; d++)
428    {
429       rank += (hypre_IndexD(index, d) - hypre_BoxIMinD(box, d)) * size;
430       size *= hypre_BoxSizeD(box, d);
431    }
432 
433    return rank;
434 }
435 
436 /*--------------------------------------------------------------------------
437  * Computes an index into a multi-D box from a rank where the assumed ordering
438  * is dimension 0 first, then dimension 1, etc.
439  *--------------------------------------------------------------------------*/
440 
441 HYPRE_Int
hypre_BoxRankIndex(hypre_Box * box,HYPRE_Int rank,hypre_Index index)442 hypre_BoxRankIndex( hypre_Box   *box,
443                     HYPRE_Int    rank,
444                     hypre_Index  index )
445 {
446    HYPRE_Int  d, r, s, ndim = hypre_BoxNDim(box);
447 
448    r = rank;
449    s = hypre_BoxVolume(box);
450    for (d = ndim-1; d >= 0; d--)
451    {
452       s = s / hypre_BoxSizeD(box, d);
453       hypre_IndexD(index, d) = r / s;
454       hypre_IndexD(index, d) += hypre_BoxIMinD(box, d);
455       r = r % s;
456    }
457 
458    return hypre_error_flag;
459 }
460 
461 /*--------------------------------------------------------------------------
462  * Returns the distance of an index offset in a multi-D box where the assumed
463  * ordering is dimension 0 first, then dimension 1, etc.
464  *--------------------------------------------------------------------------*/
465 
466 HYPRE_Int
hypre_BoxOffsetDistance(hypre_Box * box,hypre_Index index)467 hypre_BoxOffsetDistance( hypre_Box   *box,
468                          hypre_Index  index )
469 {
470    HYPRE_Int  dist, size, d, ndim = hypre_BoxNDim(box);
471 
472    dist = 0;
473    size = 1;
474    for (d = 0; d < ndim; d++)
475    {
476       dist += hypre_IndexD(index, d) * size;
477       size *= hypre_BoxSizeD(box, d);
478    }
479 
480    return dist;
481 }
482 
483 /*--------------------------------------------------------------------------
484  * Shift a box by a positive shift
485  *--------------------------------------------------------------------------*/
486 
487 HYPRE_Int
hypre_BoxShiftPos(hypre_Box * box,hypre_Index shift)488 hypre_BoxShiftPos( hypre_Box   *box,
489                    hypre_Index  shift )
490 {
491    HYPRE_Int  d, ndim = hypre_BoxNDim(box);
492 
493    for (d = 0; d < ndim; d++)
494    {
495       hypre_BoxIMinD(box, d) += hypre_IndexD(shift, d);
496       hypre_BoxIMaxD(box, d) += hypre_IndexD(shift, d);
497    }
498 
499    return hypre_error_flag;
500 }
501 
502 /*--------------------------------------------------------------------------
503  * Shift a box by a negative shift
504  *--------------------------------------------------------------------------*/
505 
506 HYPRE_Int
hypre_BoxShiftNeg(hypre_Box * box,hypre_Index shift)507 hypre_BoxShiftNeg( hypre_Box   *box,
508                    hypre_Index  shift )
509 {
510    HYPRE_Int  d, ndim = hypre_BoxNDim(box);
511 
512    for (d = 0; d < ndim; d++)
513    {
514       hypre_BoxIMinD(box, d) -= hypre_IndexD(shift, d);
515       hypre_BoxIMaxD(box, d) -= hypre_IndexD(shift, d);
516    }
517 
518    return hypre_error_flag;
519 }
520 
521 /*--------------------------------------------------------------------------
522  * Grow a box outward in each dimension as specified by index
523  *--------------------------------------------------------------------------*/
524 
525 HYPRE_Int
hypre_BoxGrowByIndex(hypre_Box * box,hypre_Index index)526 hypre_BoxGrowByIndex( hypre_Box   *box,
527                       hypre_Index  index )
528 {
529    hypre_IndexRef  imin = hypre_BoxIMin(box);
530    hypre_IndexRef  imax = hypre_BoxIMax(box);
531    HYPRE_Int       ndim = hypre_BoxNDim(box);
532    HYPRE_Int       d, i;
533 
534    for (d = 0; d < ndim; d++)
535    {
536       i = hypre_IndexD(index, d);
537       hypre_IndexD(imin, d) -= i;
538       hypre_IndexD(imax, d) += i;
539    }
540 
541    return hypre_error_flag;
542 }
543 
544 /*--------------------------------------------------------------------------
545  * Grow a box outward by val in each dimension
546  *--------------------------------------------------------------------------*/
547 
548 HYPRE_Int
hypre_BoxGrowByValue(hypre_Box * box,HYPRE_Int val)549 hypre_BoxGrowByValue( hypre_Box  *box,
550                       HYPRE_Int   val )
551 {
552    HYPRE_Int  *imin = hypre_BoxIMin(box);
553    HYPRE_Int  *imax = hypre_BoxIMax(box);
554    HYPRE_Int   ndim = hypre_BoxNDim(box);
555    HYPRE_Int  d;
556 
557    for (d = 0; d < ndim; d++)
558    {
559       hypre_IndexD(imin, d) -= val;
560       hypre_IndexD(imax, d) += val;
561    }
562 
563    return hypre_error_flag;
564 }
565 
566 /*--------------------------------------------------------------------------
567  * Grow a box as specified by array
568  *--------------------------------------------------------------------------*/
569 
570 HYPRE_Int
hypre_BoxGrowByArray(hypre_Box * box,HYPRE_Int * array)571 hypre_BoxGrowByArray( hypre_Box  *box,
572                       HYPRE_Int  *array )
573 {
574    HYPRE_Int  *imin = hypre_BoxIMin(box);
575    HYPRE_Int  *imax = hypre_BoxIMax(box);
576    HYPRE_Int   ndim = hypre_BoxNDim(box);
577    HYPRE_Int   d;
578 
579    for (d = 0; d < ndim; d++)
580    {
581       imin[d] -= array[2*d];
582       imax[d] += array[2*d+1];
583    }
584 
585    return hypre_error_flag;
586 }
587 
588 /*==========================================================================
589  * Member functions: hypre_BoxArray
590  *==========================================================================*/
591 
592 /*--------------------------------------------------------------------------
593  *--------------------------------------------------------------------------*/
594 
595 hypre_BoxArray *
hypre_BoxArrayCreate(HYPRE_Int size,HYPRE_Int ndim)596 hypre_BoxArrayCreate( HYPRE_Int size,
597                       HYPRE_Int ndim )
598 {
599    HYPRE_Int       i;
600    hypre_Box      *box;
601    hypre_BoxArray *box_array;
602 
603    box_array = hypre_TAlloc(hypre_BoxArray,  1, HYPRE_MEMORY_HOST);
604 
605    hypre_BoxArrayBoxes(box_array)     = hypre_CTAlloc(hypre_Box,  size, HYPRE_MEMORY_HOST);
606    hypre_BoxArraySize(box_array)      = size;
607    hypre_BoxArrayAllocSize(box_array) = size;
608    hypre_BoxArrayNDim(box_array)      = ndim;
609    for (i = 0; i < size; i++)
610    {
611       box = hypre_BoxArrayBox(box_array, i);
612       hypre_BoxNDim(box) = ndim;
613    }
614 
615    return box_array;
616 }
617 
618 /*--------------------------------------------------------------------------
619  *--------------------------------------------------------------------------*/
620 
621 HYPRE_Int
hypre_BoxArrayDestroy(hypre_BoxArray * box_array)622 hypre_BoxArrayDestroy( hypre_BoxArray *box_array )
623 {
624    if (box_array)
625    {
626       hypre_TFree(hypre_BoxArrayBoxes(box_array), HYPRE_MEMORY_HOST);
627       hypre_TFree(box_array, HYPRE_MEMORY_HOST);
628    }
629 
630    return hypre_error_flag;
631 }
632 
633 /*--------------------------------------------------------------------------
634  *--------------------------------------------------------------------------*/
635 
636 HYPRE_Int
hypre_BoxArraySetSize(hypre_BoxArray * box_array,HYPRE_Int size)637 hypre_BoxArraySetSize( hypre_BoxArray  *box_array,
638                        HYPRE_Int        size      )
639 {
640    HYPRE_Int  alloc_size;
641 
642    alloc_size = hypre_BoxArrayAllocSize(box_array);
643 
644    if (size > alloc_size)
645    {
646       HYPRE_Int  i, old_alloc_size, ndim = hypre_BoxArrayNDim(box_array);
647       hypre_Box *box;
648 
649       old_alloc_size = alloc_size;
650       alloc_size = size + hypre_BoxArrayExcess;
651       hypre_BoxArrayBoxes(box_array) =
652          hypre_TReAlloc(hypre_BoxArrayBoxes(box_array),  hypre_Box,  alloc_size, HYPRE_MEMORY_HOST);
653       hypre_BoxArrayAllocSize(box_array) = alloc_size;
654 
655       for (i = old_alloc_size; i < alloc_size; i++)
656       {
657          box = hypre_BoxArrayBox(box_array, i);
658          hypre_BoxNDim(box) = ndim;
659       }
660    }
661 
662    hypre_BoxArraySize(box_array) = size;
663 
664    return hypre_error_flag;
665 }
666 
667 /*--------------------------------------------------------------------------
668  * Return a duplicate box_array.
669  *--------------------------------------------------------------------------*/
670 
671 hypre_BoxArray *
hypre_BoxArrayDuplicate(hypre_BoxArray * box_array)672 hypre_BoxArrayDuplicate( hypre_BoxArray *box_array )
673 {
674    hypre_BoxArray  *new_box_array;
675 
676    HYPRE_Int        i;
677 
678    new_box_array = hypre_BoxArrayCreate(
679       hypre_BoxArraySize(box_array), hypre_BoxArrayNDim(box_array));
680    hypre_ForBoxI(i, box_array)
681    {
682       hypre_CopyBox(hypre_BoxArrayBox(box_array, i),
683                     hypre_BoxArrayBox(new_box_array, i));
684    }
685 
686    return new_box_array;
687 }
688 
689 /*--------------------------------------------------------------------------
690  * Append box to the end of box_array.
691  * The box_array may be empty.
692  *--------------------------------------------------------------------------*/
693 
694 HYPRE_Int
hypre_AppendBox(hypre_Box * box,hypre_BoxArray * box_array)695 hypre_AppendBox( hypre_Box      *box,
696                  hypre_BoxArray *box_array )
697 {
698    HYPRE_Int  size;
699 
700    size = hypre_BoxArraySize(box_array);
701    hypre_BoxArraySetSize(box_array, (size + 1));
702    hypre_CopyBox(box, hypre_BoxArrayBox(box_array, size));
703 
704    return hypre_error_flag;
705 }
706 
707 /*--------------------------------------------------------------------------
708  * Delete box from box_array.
709  *--------------------------------------------------------------------------*/
710 
711 HYPRE_Int
hypre_DeleteBox(hypre_BoxArray * box_array,HYPRE_Int index)712 hypre_DeleteBox( hypre_BoxArray *box_array,
713                  HYPRE_Int       index     )
714 {
715    HYPRE_Int  i;
716 
717    for (i = index; i < hypre_BoxArraySize(box_array) - 1; i++)
718    {
719       hypre_CopyBox(hypre_BoxArrayBox(box_array, i+1),
720                     hypre_BoxArrayBox(box_array, i));
721    }
722 
723    hypre_BoxArraySize(box_array) --;
724 
725    return hypre_error_flag;
726 }
727 
728 /*--------------------------------------------------------------------------
729  * Deletes boxes corrsponding to indices from box_array.
730  * Assumes indices are in ascending order. (AB 11/04)
731  *--------------------------------------------------------------------------*/
732 
733 HYPRE_Int
hypre_DeleteMultipleBoxes(hypre_BoxArray * box_array,HYPRE_Int * indices,HYPRE_Int num)734 hypre_DeleteMultipleBoxes( hypre_BoxArray *box_array,
735                            HYPRE_Int*  indices,
736                            HYPRE_Int num )
737 {
738    HYPRE_Int  i, j, start, array_size;
739 
740    if (num < 1)
741    {
742       return hypre_error_flag;
743    }
744 
745    array_size =  hypre_BoxArraySize(box_array);
746    start = indices[0];
747    j = 0;
748 
749    for (i = start; (i + j) < array_size; i++)
750    {
751       if (j < num)
752       {
753          while ((i+j) == indices[j]) /* see if deleting consecutive items */
754          {
755             j++; /*increase the shift*/
756             if (j == num) break;
757          }
758       }
759 
760       if ( (i+j) < array_size)  /* if deleting the last item then no moving */
761       {
762          hypre_CopyBox(hypre_BoxArrayBox(box_array, i+j),
763                        hypre_BoxArrayBox(box_array, i));
764       }
765    }
766 
767    hypre_BoxArraySize(box_array) = array_size - num;
768 
769    return hypre_error_flag;
770 }
771 
772 /*--------------------------------------------------------------------------
773  * Append box_array_0 to the end of box_array_1.
774  * The box_array_1 may be empty.
775  *--------------------------------------------------------------------------*/
776 
777 HYPRE_Int
hypre_AppendBoxArray(hypre_BoxArray * box_array_0,hypre_BoxArray * box_array_1)778 hypre_AppendBoxArray( hypre_BoxArray *box_array_0,
779                       hypre_BoxArray *box_array_1 )
780 {
781    HYPRE_Int  size, size_0;
782    HYPRE_Int  i;
783 
784    size   = hypre_BoxArraySize(box_array_1);
785    size_0 = hypre_BoxArraySize(box_array_0);
786    hypre_BoxArraySetSize(box_array_1, (size + size_0));
787 
788    /* copy box_array_0 boxes into box_array_1 */
789    for (i = 0; i < size_0; i++)
790    {
791       hypre_CopyBox(hypre_BoxArrayBox(box_array_0, i),
792                     hypre_BoxArrayBox(box_array_1, size + i));
793    }
794 
795    return hypre_error_flag;
796 }
797 
798 /*==========================================================================
799  * Member functions: hypre_BoxArrayArray
800  *==========================================================================*/
801 
802 /*--------------------------------------------------------------------------
803  *--------------------------------------------------------------------------*/
804 
805 hypre_BoxArrayArray *
hypre_BoxArrayArrayCreate(HYPRE_Int size,HYPRE_Int ndim)806 hypre_BoxArrayArrayCreate( HYPRE_Int size,
807                            HYPRE_Int ndim )
808 {
809    hypre_BoxArrayArray  *box_array_array;
810    HYPRE_Int             i;
811 
812    box_array_array = hypre_CTAlloc(hypre_BoxArrayArray,  1, HYPRE_MEMORY_HOST);
813 
814    hypre_BoxArrayArrayBoxArrays(box_array_array) =
815       hypre_CTAlloc(hypre_BoxArray *,  size, HYPRE_MEMORY_HOST);
816 
817    for (i = 0; i < size; i++)
818    {
819       hypre_BoxArrayArrayBoxArray(box_array_array, i) =
820          hypre_BoxArrayCreate(0, ndim);
821    }
822    hypre_BoxArrayArraySize(box_array_array) = size;
823    hypre_BoxArrayArrayNDim(box_array_array) = ndim;
824 
825    return box_array_array;
826 }
827 
828 /*--------------------------------------------------------------------------
829  *--------------------------------------------------------------------------*/
830 
831 HYPRE_Int
hypre_BoxArrayArrayDestroy(hypre_BoxArrayArray * box_array_array)832 hypre_BoxArrayArrayDestroy( hypre_BoxArrayArray *box_array_array )
833 {
834    HYPRE_Int  i;
835 
836    if (box_array_array)
837    {
838       hypre_ForBoxArrayI(i, box_array_array)
839          hypre_BoxArrayDestroy(
840             hypre_BoxArrayArrayBoxArray(box_array_array, i));
841 
842       hypre_TFree(hypre_BoxArrayArrayBoxArrays(box_array_array), HYPRE_MEMORY_HOST);
843       hypre_TFree(box_array_array, HYPRE_MEMORY_HOST);
844    }
845 
846    return hypre_error_flag;
847 }
848 
849 /*--------------------------------------------------------------------------
850  * Return a duplicate box_array_array.
851  *--------------------------------------------------------------------------*/
852 
853 hypre_BoxArrayArray *
hypre_BoxArrayArrayDuplicate(hypre_BoxArrayArray * box_array_array)854 hypre_BoxArrayArrayDuplicate( hypre_BoxArrayArray *box_array_array )
855 {
856    hypre_BoxArrayArray  *new_box_array_array;
857    hypre_BoxArray      **new_box_arrays;
858    HYPRE_Int             new_size;
859 
860    hypre_BoxArray      **box_arrays;
861    HYPRE_Int             i;
862 
863    new_size = hypre_BoxArrayArraySize(box_array_array);
864    new_box_array_array = hypre_BoxArrayArrayCreate(
865       new_size, hypre_BoxArrayArrayNDim(box_array_array));
866 
867    if (new_size)
868    {
869       new_box_arrays = hypre_BoxArrayArrayBoxArrays(new_box_array_array);
870       box_arrays     = hypre_BoxArrayArrayBoxArrays(box_array_array);
871 
872       for (i = 0; i < new_size; i++)
873       {
874          hypre_AppendBoxArray(box_arrays[i], new_box_arrays[i]);
875       }
876    }
877 
878    return new_box_array_array;
879 }
880