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_StructVector class.
11  *
12  *****************************************************************************/
13 
14 #include "_hypre_struct_mv.h"
15 #include "_hypre_struct_mv.hpp"
16 
17 /*--------------------------------------------------------------------------
18  *--------------------------------------------------------------------------*/
19 
20 hypre_StructVector *
hypre_StructVectorCreate(MPI_Comm comm,hypre_StructGrid * grid)21 hypre_StructVectorCreate( MPI_Comm          comm,
22                           hypre_StructGrid *grid )
23 {
24    HYPRE_Int            ndim = hypre_StructGridNDim(grid);
25    hypre_StructVector  *vector;
26    HYPRE_Int            i;
27 
28    vector = hypre_CTAlloc(hypre_StructVector,  1, HYPRE_MEMORY_HOST);
29 
30    hypre_StructVectorComm(vector)           = comm;
31    hypre_StructGridRef(grid, &hypre_StructVectorGrid(vector));
32    hypre_StructVectorDataAlloced(vector)    = 1;
33    hypre_StructVectorBGhostNotClear(vector) = 0;
34    hypre_StructVectorRefCount(vector)       = 1;
35 
36    /* set defaults */
37    for (i = 0; i < 2*ndim; i++)
38    {
39       hypre_StructVectorNumGhost(vector)[i] = hypre_StructGridNumGhost(grid)[i];
40    }
41 
42    return vector;
43 }
44 
45 /*--------------------------------------------------------------------------
46  *--------------------------------------------------------------------------*/
47 
48 hypre_StructVector *
hypre_StructVectorRef(hypre_StructVector * vector)49 hypre_StructVectorRef( hypre_StructVector *vector )
50 {
51    hypre_StructVectorRefCount(vector) ++;
52 
53    return vector;
54 }
55 
56 /*--------------------------------------------------------------------------
57  *--------------------------------------------------------------------------*/
58 
59 HYPRE_Int
hypre_StructVectorDestroy(hypre_StructVector * vector)60 hypre_StructVectorDestroy( hypre_StructVector *vector )
61 {
62    if (vector)
63    {
64       hypre_StructVectorRefCount(vector) --;
65       if (hypre_StructVectorRefCount(vector) == 0)
66       {
67          if (hypre_StructVectorDataAlloced(vector))
68          {
69 #if 0 //defined(HYPRE_USING_CUDA) || defined(HYPRE_USING_HIP)
70             hypre_StructGrid     *grid = hypre_StructVectorGrid(vector);
71             if (hypre_StructGridDataLocation(grid) != HYPRE_MEMORY_HOST)
72             {
73                hypre_TFree(hypre_StructVectorData(vector),HYPRE_MEMORY_DEVICE);
74             }
75             else
76             {
77                hypre_TFree(hypre_StructVectorData(vector),HYPRE_MEMORY_HOST);
78             }
79 #else
80             hypre_TFree(hypre_StructVectorData(vector),HYPRE_MEMORY_DEVICE);
81 #endif
82          }
83          hypre_TFree(hypre_StructVectorDataIndices(vector), HYPRE_MEMORY_HOST);
84          hypre_BoxArrayDestroy(hypre_StructVectorDataSpace(vector));
85          hypre_StructGridDestroy(hypre_StructVectorGrid(vector));
86          hypre_TFree(vector, HYPRE_MEMORY_HOST);
87       }
88    }
89 
90    return hypre_error_flag;
91 }
92 
93 /*--------------------------------------------------------------------------
94  *--------------------------------------------------------------------------*/
95 
96 HYPRE_Int
hypre_StructVectorInitializeShell(hypre_StructVector * vector)97 hypre_StructVectorInitializeShell( hypre_StructVector *vector )
98 {
99    HYPRE_Int             ndim = hypre_StructVectorNDim(vector);
100    hypre_StructGrid     *grid;
101 
102    HYPRE_Int            *num_ghost;
103 
104    hypre_BoxArray       *data_space;
105    hypre_BoxArray       *boxes;
106    hypre_Box            *box;
107    hypre_Box            *data_box;
108 
109    HYPRE_Int            *data_indices;
110    HYPRE_Int             data_size;
111 
112    HYPRE_Int             i, d;
113 
114    /*-----------------------------------------------------------------------
115     * Set up data_space
116     *-----------------------------------------------------------------------*/
117 
118    grid = hypre_StructVectorGrid(vector);
119 
120    if (hypre_StructVectorDataSpace(vector) == NULL)
121    {
122       num_ghost = hypre_StructVectorNumGhost(vector);
123 
124       boxes = hypre_StructGridBoxes(grid);
125       data_space = hypre_BoxArrayCreate(hypre_BoxArraySize(boxes), ndim);
126 
127       hypre_ForBoxI(i, boxes)
128       {
129          box = hypre_BoxArrayBox(boxes, i);
130          data_box = hypre_BoxArrayBox(data_space, i);
131 
132          hypre_CopyBox(box, data_box);
133          for (d = 0; d < ndim; d++)
134          {
135             hypre_BoxIMinD(data_box, d) -= num_ghost[2*d];
136             hypre_BoxIMaxD(data_box, d) += num_ghost[2*d + 1];
137          }
138       }
139 
140       hypre_StructVectorDataSpace(vector) = data_space;
141    }
142 
143    /*-----------------------------------------------------------------------
144     * Set up data_indices array and data_size
145     *-----------------------------------------------------------------------*/
146 
147    if (hypre_StructVectorDataIndices(vector) == NULL)
148    {
149       data_space = hypre_StructVectorDataSpace(vector);
150       data_indices = hypre_CTAlloc(HYPRE_Int,  hypre_BoxArraySize(data_space), HYPRE_MEMORY_HOST);
151 
152       data_size = 0;
153       hypre_ForBoxI(i, data_space)
154       {
155          data_box = hypre_BoxArrayBox(data_space, i);
156 
157          data_indices[i] = data_size;
158          data_size += hypre_BoxVolume(data_box);
159       }
160 
161       hypre_StructVectorDataIndices(vector) = data_indices;
162 
163       hypre_StructVectorDataSize(vector)    = data_size;
164 
165    }
166 
167    /*-----------------------------------------------------------------------
168     * Set total number of nonzero coefficients
169     *-----------------------------------------------------------------------*/
170 
171    hypre_StructVectorGlobalSize(vector) = hypre_StructGridGlobalSize(grid);
172 
173    return hypre_error_flag;
174 }
175 
176 /*--------------------------------------------------------------------------
177  *--------------------------------------------------------------------------*/
178 
179 HYPRE_Int
hypre_StructVectorInitializeData(hypre_StructVector * vector,HYPRE_Complex * data)180 hypre_StructVectorInitializeData( hypre_StructVector *vector,
181                                   HYPRE_Complex      *data)
182 {
183    hypre_StructVectorData(vector) = data;
184    hypre_StructVectorDataAlloced(vector) = 0;
185 
186    return hypre_error_flag;
187 }
188 
189 /*--------------------------------------------------------------------------
190  *--------------------------------------------------------------------------*/
191 
192 HYPRE_Int
hypre_StructVectorInitialize(hypre_StructVector * vector)193 hypre_StructVectorInitialize( hypre_StructVector *vector )
194 {
195    HYPRE_Complex *data;
196 
197    hypre_StructVectorInitializeShell(vector);
198 #if 0 //defined(HYPRE_USING_CUDA) || defined(HYPRE_USING_HIP)
199    hypre_StructGrid     *grid = hypre_StructVectorGrid(vector);
200    if (hypre_StructGridDataLocation(grid) != HYPRE_MEMORY_HOST)
201    {
202       data = hypre_CTAlloc(HYPRE_Complex, hypre_StructVectorDataSize(vector),HYPRE_MEMORY_DEVICE);
203    }
204    else
205    {
206       data = hypre_CTAlloc(HYPRE_Complex, hypre_StructVectorDataSize(vector),HYPRE_MEMORY_HOST);
207    }
208 #else
209    data = hypre_CTAlloc(HYPRE_Complex, hypre_StructVectorDataSize(vector),HYPRE_MEMORY_DEVICE);
210 #endif
211 
212    hypre_StructVectorInitializeData(vector, data);
213    hypre_StructVectorDataAlloced(vector) = 1;
214 
215    return hypre_error_flag;
216 }
217 
218 /*--------------------------------------------------------------------------
219  * (action > 0): add-to values
220  * (action = 0): set values
221  * (action < 0): get values
222  *
223  * (outside > 0): set values possibly outside of the grid extents
224  * (outside = 0): set values only inside the grid extents
225  *
226  * NOTE: Getting and setting values outside of the grid extents requires care,
227  * as these values may be stored in multiple ghost zone locations.
228  *--------------------------------------------------------------------------*/
229 
230 HYPRE_Int
hypre_StructVectorSetValues(hypre_StructVector * vector,hypre_Index grid_index,HYPRE_Complex * values,HYPRE_Int action,HYPRE_Int boxnum,HYPRE_Int outside)231 hypre_StructVectorSetValues( hypre_StructVector *vector,
232                              hypre_Index         grid_index,
233                              HYPRE_Complex      *values,
234                              HYPRE_Int           action,
235                              HYPRE_Int           boxnum,
236                              HYPRE_Int           outside    )
237 {
238    hypre_BoxArray     *grid_boxes;
239    hypre_Box          *grid_box;
240 
241    HYPRE_Complex      *vecp;
242 
243    HYPRE_Int           i, istart, istop;
244 
245    if (outside > 0)
246    {
247       grid_boxes = hypre_StructVectorDataSpace(vector);
248    }
249    else
250    {
251       grid_boxes = hypre_StructGridBoxes(hypre_StructVectorGrid(vector));
252    }
253 
254    if (boxnum < 0)
255    {
256       istart = 0;
257       istop  = hypre_BoxArraySize(grid_boxes);
258    }
259    else
260    {
261       istart = boxnum;
262       istop  = istart + 1;
263    }
264 
265    for (i = istart; i < istop; i++)
266    {
267       grid_box = hypre_BoxArrayBox(grid_boxes, i);
268 
269       if (hypre_IndexInBox(grid_index, grid_box))
270       {
271          vecp = hypre_StructVectorBoxDataValue(vector, i, grid_index);
272 
273          if (hypre_GetActualMemLocation(HYPRE_MEMORY_DEVICE) != hypre_MEMORY_HOST)
274          {
275             if (action > 0)
276             {
277 #define DEVICE_VAR is_device_ptr(vecp,values)
278                hypre_LoopBegin(1, k)
279                {
280                   *vecp += *values;
281                }
282                hypre_LoopEnd()
283 #undef DEVICE_VAR
284             }
285             else if (action > -1)
286             {
287                hypre_TMemcpy(vecp, values, HYPRE_Complex, 1, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_DEVICE);
288             }
289             else /* action < 0 */
290             {
291                hypre_TMemcpy(values, vecp, HYPRE_Complex, 1, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_DEVICE);
292             }
293          }
294          else
295          {
296             if (action > 0)
297             {
298                *vecp += *values;
299             }
300             else if (action > -1)
301             {
302                *vecp = *values;
303             }
304             else /* action < 0 */
305             {
306                *values = *vecp;
307             }
308          }
309       }
310    }
311 
312    return hypre_error_flag;
313 }
314 
315 /*--------------------------------------------------------------------------
316  * (action > 0): add-to values
317  * (action = 0): set values
318  * (action < 0): get values
319  *
320  * (outside > 0): set values possibly outside of the grid extents
321  * (outside = 0): set values only inside the grid extents
322  *
323  * NOTE: Getting and setting values outside of the grid extents requires care,
324  * as these values may be stored in multiple ghost zone locations.
325  *--------------------------------------------------------------------------*/
326 
327 HYPRE_Int
hypre_StructVectorSetBoxValues(hypre_StructVector * vector,hypre_Box * set_box,hypre_Box * value_box,HYPRE_Complex * values,HYPRE_Int action,HYPRE_Int boxnum,HYPRE_Int outside)328 hypre_StructVectorSetBoxValues( hypre_StructVector *vector,
329                                 hypre_Box          *set_box,
330                                 hypre_Box          *value_box,
331                                 HYPRE_Complex      *values,
332                                 HYPRE_Int           action,
333                                 HYPRE_Int           boxnum,
334                                 HYPRE_Int           outside )
335 {
336    hypre_BoxArray     *grid_boxes;
337    hypre_Box          *grid_box;
338    hypre_Box          *int_box;
339 
340    hypre_BoxArray     *data_space;
341    hypre_Box          *data_box;
342    hypre_IndexRef      data_start;
343    hypre_Index         data_stride;
344    HYPRE_Complex      *datap;
345 
346    hypre_Box          *dval_box;
347    hypre_Index         dval_start;
348    hypre_Index         dval_stride;
349 
350    hypre_Index         loop_size;
351 
352    HYPRE_Int           i, istart, istop;
353 
354    /*-----------------------------------------------------------------------
355     * Initialize some things
356     *-----------------------------------------------------------------------*/
357 
358    if (outside > 0)
359    {
360       grid_boxes = hypre_StructVectorDataSpace(vector);
361    }
362    else
363    {
364       grid_boxes = hypre_StructGridBoxes(hypre_StructVectorGrid(vector));
365    }
366    data_space = hypre_StructVectorDataSpace(vector);
367 
368    if (boxnum < 0)
369    {
370       istart = 0;
371       istop  = hypre_BoxArraySize(grid_boxes);
372    }
373    else
374    {
375       istart = boxnum;
376       istop  = istart + 1;
377    }
378 
379    /*-----------------------------------------------------------------------
380     * Set the vector coefficients
381     *-----------------------------------------------------------------------*/
382 
383    hypre_SetIndex(data_stride, 1);
384 
385    int_box = hypre_BoxCreate(hypre_StructVectorNDim(vector));
386    dval_box = hypre_BoxDuplicate(value_box);
387    hypre_SetIndex(dval_stride, 1);
388 
389    for (i = istart; i < istop; i++)
390    {
391       grid_box = hypre_BoxArrayBox(grid_boxes, i);
392       data_box = hypre_BoxArrayBox(data_space, i);
393 
394       hypre_IntersectBoxes(set_box, grid_box, int_box);
395 
396       /* if there was an intersection */
397       if (hypre_BoxVolume(int_box))
398       {
399          data_start = hypre_BoxIMin(int_box);
400          hypre_CopyIndex(data_start, dval_start);
401 
402          datap = hypre_StructVectorBoxData(vector, i);
403 
404          hypre_BoxGetSize(int_box, loop_size);
405 
406 #define DEVICE_VAR is_device_ptr(datap,values)
407          if (action > 0)
408          {
409             hypre_BoxLoop2Begin(hypre_StructVectorNDim(vector), loop_size,
410                                 data_box,data_start,data_stride,datai,
411                                 dval_box,dval_start,dval_stride,dvali);
412             {
413                datap[datai] += values[dvali];
414             }
415             hypre_BoxLoop2End(datai, dvali);
416          }
417          else if (action > -1)
418          {
419             hypre_BoxLoop2Begin(hypre_StructVectorNDim(vector), loop_size,
420                                 data_box,data_start,data_stride,datai,
421                                 dval_box,dval_start,dval_stride,dvali);
422             {
423                datap[datai] = values[dvali];
424             }
425             hypre_BoxLoop2End(datai, dvali);
426          }
427          else /* action < 0 */
428          {
429             hypre_BoxLoop2Begin(hypre_StructVectorNDim(vector), loop_size,
430                                 data_box,data_start,data_stride,datai,
431                                 dval_box,dval_start,dval_stride,dvali);
432             {
433                values[dvali] = datap[datai];
434             }
435             hypre_BoxLoop2End(datai, dvali);
436          }
437 #undef DEVICE_VAR
438       }
439    }
440 
441    hypre_BoxDestroy(int_box);
442    hypre_BoxDestroy(dval_box);
443 
444    return hypre_error_flag;
445 }
446 
447 /*--------------------------------------------------------------------------
448  * (outside > 0): clear values possibly outside of the grid extents
449  * (outside = 0): clear values only inside the grid extents
450  *--------------------------------------------------------------------------*/
451 
452 HYPRE_Int
hypre_StructVectorClearValues(hypre_StructVector * vector,hypre_Index grid_index,HYPRE_Int boxnum,HYPRE_Int outside)453 hypre_StructVectorClearValues( hypre_StructVector *vector,
454                                hypre_Index         grid_index,
455                                HYPRE_Int           boxnum,
456                                HYPRE_Int           outside    )
457 {
458    hypre_BoxArray     *grid_boxes;
459    hypre_Box          *grid_box;
460 
461    HYPRE_Complex      *vecp;
462 
463    HYPRE_Int           i, istart, istop;
464 
465    if (outside > 0)
466    {
467       grid_boxes = hypre_StructVectorDataSpace(vector);
468    }
469    else
470    {
471       grid_boxes = hypre_StructGridBoxes(hypre_StructVectorGrid(vector));
472    }
473 
474    if (boxnum < 0)
475    {
476       istart = 0;
477       istop  = hypre_BoxArraySize(grid_boxes);
478    }
479    else
480    {
481       istart = boxnum;
482       istop  = istart + 1;
483    }
484 
485    for (i = istart; i < istop; i++)
486    {
487       grid_box = hypre_BoxArrayBox(grid_boxes, i);
488 
489       if (hypre_IndexInBox(grid_index, grid_box))
490       {
491          vecp = hypre_StructVectorBoxDataValue(vector, i, grid_index);
492 
493          if (hypre_GetActualMemLocation(HYPRE_MEMORY_DEVICE) != hypre_MEMORY_HOST)
494          {
495 #define DEVICE_VAR is_device_ptr(vecp)
496             hypre_LoopBegin(1, k)
497             {
498                *vecp = 0.0;
499             }
500             hypre_LoopEnd()
501 #undef DEVICE_VAR
502          }
503          else
504          {
505             *vecp = 0.0;
506          }
507       }
508    }
509 
510    return hypre_error_flag;
511 }
512 
513 /*--------------------------------------------------------------------------
514  * (outside > 0): clear values possibly outside of the grid extents
515  * (outside = 0): clear values only inside the grid extents
516  *--------------------------------------------------------------------------*/
517 
518 HYPRE_Int
hypre_StructVectorClearBoxValues(hypre_StructVector * vector,hypre_Box * clear_box,HYPRE_Int boxnum,HYPRE_Int outside)519 hypre_StructVectorClearBoxValues( hypre_StructVector *vector,
520                                   hypre_Box          *clear_box,
521                                   HYPRE_Int           boxnum,
522                                   HYPRE_Int           outside )
523 {
524    hypre_BoxArray     *grid_boxes;
525    hypre_Box          *grid_box;
526    hypre_Box          *int_box;
527 
528    hypre_BoxArray     *data_space;
529    hypre_Box          *data_box;
530    hypre_IndexRef      data_start;
531    hypre_Index         data_stride;
532    HYPRE_Complex      *datap;
533 
534    hypre_Index         loop_size;
535 
536    HYPRE_Int           i, istart, istop;
537 
538    /*-----------------------------------------------------------------------
539     * Initialize some things
540     *-----------------------------------------------------------------------*/
541 
542    if (outside > 0)
543    {
544       grid_boxes = hypre_StructVectorDataSpace(vector);
545    }
546    else
547    {
548       grid_boxes = hypre_StructGridBoxes(hypre_StructVectorGrid(vector));
549    }
550    data_space = hypre_StructVectorDataSpace(vector);
551 
552    if (boxnum < 0)
553    {
554       istart = 0;
555       istop  = hypre_BoxArraySize(grid_boxes);
556    }
557    else
558    {
559       istart = boxnum;
560       istop  = istart + 1;
561    }
562 
563    /*-----------------------------------------------------------------------
564     * Set the vector coefficients
565     *-----------------------------------------------------------------------*/
566 
567    hypre_SetIndex(data_stride, 1);
568 
569    int_box = hypre_BoxCreate(hypre_StructVectorNDim(vector));
570 
571    for (i = istart; i < istop; i++)
572    {
573       grid_box = hypre_BoxArrayBox(grid_boxes, i);
574       data_box = hypre_BoxArrayBox(data_space, i);
575 
576       hypre_IntersectBoxes(clear_box, grid_box, int_box);
577 
578       /* if there was an intersection */
579       if (hypre_BoxVolume(int_box))
580       {
581          data_start = hypre_BoxIMin(int_box);
582 
583          datap = hypre_StructVectorBoxData(vector, i);
584 
585          hypre_BoxGetSize(int_box, loop_size);
586 
587 #define DEVICE_VAR is_device_ptr(datap)
588          hypre_BoxLoop1Begin(hypre_StructVectorNDim(vector), loop_size,
589                              data_box,data_start,data_stride,datai);
590          {
591             datap[datai] = 0.0;
592          }
593          hypre_BoxLoop1End(datai);
594 #undef DEVICE_VAR
595       }
596    }
597 
598    hypre_BoxDestroy(int_box);
599 
600    return hypre_error_flag;
601 }
602 
603 /*--------------------------------------------------------------------------
604  *--------------------------------------------------------------------------*/
605 
606 HYPRE_Int
hypre_StructVectorClearAllValues(hypre_StructVector * vector)607 hypre_StructVectorClearAllValues( hypre_StructVector *vector )
608 {
609    HYPRE_Complex *data      = hypre_StructVectorData(vector);
610    HYPRE_Int      data_size = hypre_StructVectorDataSize(vector);
611    hypre_Index    imin, imax;
612    hypre_Box     *box;
613 
614    box = hypre_BoxCreate(1);
615    hypre_IndexD(imin, 0) = 1;
616    hypre_IndexD(imax, 0) = data_size;
617    hypre_BoxSetExtents(box, imin, imax);
618 
619 #define DEVICE_VAR is_device_ptr(data)
620    hypre_BoxLoop1Begin(1, imax,
621                        box, imin, imin, datai);
622    {
623       data[datai] = 0.0;
624    }
625    hypre_BoxLoop1End(datai);
626 #undef DEVICE_VAR
627 
628    hypre_BoxDestroy(box);
629 
630    return hypre_error_flag;
631 }
632 
633 /*--------------------------------------------------------------------------
634  *--------------------------------------------------------------------------*/
635 
636 HYPRE_Int
hypre_StructVectorSetNumGhost(hypre_StructVector * vector,HYPRE_Int * num_ghost)637 hypre_StructVectorSetNumGhost( hypre_StructVector *vector,
638                                HYPRE_Int          *num_ghost )
639 {
640    HYPRE_Int  d, ndim = hypre_StructVectorNDim(vector);
641 
642    for (d = 0; d < ndim; d++)
643    {
644       hypre_StructVectorNumGhost(vector)[2*d]     = num_ghost[2*d];
645       hypre_StructVectorNumGhost(vector)[2*d + 1] = num_ghost[2*d + 1];
646    }
647 
648    return hypre_error_flag;
649 }
650 
651 /*--------------------------------------------------------------------------
652  *--------------------------------------------------------------------------*/
653 
654 HYPRE_Int
hypre_StructVectorSetDataSize(hypre_StructVector * vector,HYPRE_Int * data_size,HYPRE_Int * data_host_size)655 hypre_StructVectorSetDataSize(hypre_StructVector *vector,
656                               HYPRE_Int          *data_size,
657                               HYPRE_Int          *data_host_size)
658 {
659 #if 0 //defined(HYPRE_USING_CUDA) || defined(HYPRE_USING_HIP)
660    hypre_StructGrid     *grid = hypre_StructVectorGrid(vector);
661    if (hypre_StructGridDataLocation(grid) != HYPRE_MEMORY_HOST)
662    {
663       *data_size += hypre_StructVectorDataSize(vector);
664    }
665    else
666    {
667       *data_host_size += hypre_StructVectorDataSize(vector);
668    }
669 #else
670    *data_size += hypre_StructVectorDataSize(vector);
671 #endif
672    return hypre_error_flag;
673 }
674 
675 /*--------------------------------------------------------------------------
676  *--------------------------------------------------------------------------*/
677 
678 HYPRE_Int
hypre_StructVectorAssemble(hypre_StructVector * vector)679 hypre_StructVectorAssemble( hypre_StructVector *vector )
680 {
681    return hypre_error_flag;
682 }
683 
684 /*--------------------------------------------------------------------------
685  * copies data from x to y
686  * y has its own data array, so this is a deep copy in that sense.
687  * The grid and other size information are not copied - they are
688  * assumed to have already been set up to be consistent.
689  *--------------------------------------------------------------------------*/
690 
691 HYPRE_Int
hypre_StructVectorCopy(hypre_StructVector * x,hypre_StructVector * y)692 hypre_StructVectorCopy( hypre_StructVector *x,
693                         hypre_StructVector *y )
694 {
695    hypre_Box          *x_data_box;
696 
697    HYPRE_Complex      *xp, *yp;
698 
699    hypre_BoxArray     *boxes;
700    hypre_Box          *box;
701    hypre_Index         loop_size;
702    hypre_IndexRef      start;
703    hypre_Index         unit_stride;
704 
705    HYPRE_Int           i;
706 
707    /*-----------------------------------------------------------------------
708     * Set the vector coefficients
709     *-----------------------------------------------------------------------*/
710 
711    hypre_SetIndex(unit_stride, 1);
712 
713    boxes = hypre_StructGridBoxes( hypre_StructVectorGrid(x) );
714    hypre_ForBoxI(i, boxes)
715    {
716       box      = hypre_BoxArrayBox(boxes, i);
717       start = hypre_BoxIMin(box);
718 
719       x_data_box =
720          hypre_BoxArrayBox(hypre_StructVectorDataSpace(x), i);
721       xp = hypre_StructVectorBoxData(x, i);
722       yp = hypre_StructVectorBoxData(y, i);
723 
724       hypre_BoxGetSize(box, loop_size);
725 
726 #define DEVICE_VAR is_device_ptr(yp,xp)
727       hypre_BoxLoop1Begin(hypre_StructVectorNDim(x), loop_size,
728                           x_data_box, start, unit_stride, vi);
729       {
730          yp[vi] = xp[vi];
731       }
732       hypre_BoxLoop1End(vi);
733 #undef DEVICE_VAR
734    }
735 
736    return hypre_error_flag;
737 }
738 
739 /*--------------------------------------------------------------------------
740  *--------------------------------------------------------------------------*/
741 
742 HYPRE_Int
hypre_StructVectorSetConstantValues(hypre_StructVector * vector,HYPRE_Complex values)743 hypre_StructVectorSetConstantValues( hypre_StructVector *vector,
744                                      HYPRE_Complex       values )
745 {
746    hypre_Box          *v_data_box;
747 
748    HYPRE_Complex      *vp;
749 
750    hypre_BoxArray     *boxes;
751    hypre_Box          *box;
752    hypre_Index         loop_size;
753    hypre_IndexRef      start;
754    hypre_Index         unit_stride;
755 
756    HYPRE_Int           i;
757 
758    /*-----------------------------------------------------------------------
759     * Set the vector coefficients
760     *-----------------------------------------------------------------------*/
761 
762    hypre_SetIndex(unit_stride, 1);
763 
764    boxes = hypre_StructGridBoxes(hypre_StructVectorGrid(vector));
765    hypre_ForBoxI(i, boxes)
766    {
767       box      = hypre_BoxArrayBox(boxes, i);
768       start = hypre_BoxIMin(box);
769 
770       v_data_box =
771          hypre_BoxArrayBox(hypre_StructVectorDataSpace(vector), i);
772       vp = hypre_StructVectorBoxData(vector, i);
773 
774       hypre_BoxGetSize(box, loop_size);
775 
776 #define DEVICE_VAR is_device_ptr(vp)
777       hypre_BoxLoop1Begin(hypre_StructVectorNDim(vector), loop_size,
778                           v_data_box, start, unit_stride, vi);
779       {
780          vp[vi] = values;
781       }
782       hypre_BoxLoop1End(vi);
783 #undef DEVICE_VAR
784    }
785 
786    return hypre_error_flag;
787 }
788 
789 /*--------------------------------------------------------------------------
790  * Takes a function pointer of the form:  HYPRE_Complex  f(i,j,k)
791  * RDF: This function doesn't appear to be used anywhere.
792  *--------------------------------------------------------------------------*/
793 
794 /* ONLY3D */
795 
796 HYPRE_Int
hypre_StructVectorSetFunctionValues(hypre_StructVector * vector,HYPRE_Complex (* fcn)(HYPRE_Int,HYPRE_Int,HYPRE_Int))797 hypre_StructVectorSetFunctionValues( hypre_StructVector *vector,
798                                      HYPRE_Complex     (*fcn)(HYPRE_Int, HYPRE_Int, HYPRE_Int) )
799 {
800    hypre_Box          *v_data_box;
801 
802    HYPRE_Complex      *vp;
803 
804    hypre_BoxArray     *boxes;
805    hypre_Box          *box;
806    hypre_Index         loop_size;
807    hypre_IndexRef      start;
808    hypre_Index         unit_stride;
809 
810    HYPRE_Int           b, i, j, k;
811 
812    /*-----------------------------------------------------------------------
813     * Set the vector coefficients
814     *-----------------------------------------------------------------------*/
815 
816    hypre_SetIndex(unit_stride, 1);
817 
818    boxes = hypre_StructGridBoxes(hypre_StructVectorGrid(vector));
819    hypre_ForBoxI(b, boxes)
820    {
821       box      = hypre_BoxArrayBox(boxes, b);
822       start = hypre_BoxIMin(box);
823 
824       v_data_box =
825          hypre_BoxArrayBox(hypre_StructVectorDataSpace(vector), b);
826       vp = hypre_StructVectorBoxData(vector, b);
827 
828       hypre_BoxGetSize(box, loop_size);
829 
830       i = hypre_IndexD(start, 0);
831       j = hypre_IndexD(start, 1);
832       k = hypre_IndexD(start, 2);
833 
834       hypre_SerialBoxLoop1Begin(hypre_StructVectorNDim(vector), loop_size,
835                                 v_data_box, start, unit_stride, vi)
836       {
837          vp[vi] = fcn(i, j, k);
838          i++;
839          j++;
840          k++;
841       }
842       hypre_SerialBoxLoop1End(vi)
843    }
844 
845    return hypre_error_flag;
846 }
847 
848 /*--------------------------------------------------------------------------
849  *--------------------------------------------------------------------------*/
850 
851 HYPRE_Int
hypre_StructVectorClearGhostValues(hypre_StructVector * vector)852 hypre_StructVectorClearGhostValues( hypre_StructVector *vector )
853 {
854    HYPRE_Int           ndim = hypre_StructVectorNDim(vector);
855    hypre_Box          *v_data_box;
856 
857    HYPRE_Complex      *vp;
858 
859    hypre_BoxArray     *boxes;
860    hypre_Box          *box;
861    hypre_BoxArray     *diff_boxes;
862    hypre_Box          *diff_box;
863    hypre_Index         loop_size;
864    hypre_IndexRef      start;
865    hypre_Index         unit_stride;
866 
867    HYPRE_Int           i, j;
868 
869    /*-----------------------------------------------------------------------
870     * Set the vector coefficients
871     *-----------------------------------------------------------------------*/
872 
873    hypre_SetIndex(unit_stride, 1);
874 
875    boxes = hypre_StructGridBoxes(hypre_StructVectorGrid(vector));
876    diff_boxes = hypre_BoxArrayCreate(0, ndim);
877    hypre_ForBoxI(i, boxes)
878    {
879       box        = hypre_BoxArrayBox(boxes, i);
880       v_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(vector), i);
881       hypre_BoxArraySetSize(diff_boxes, 0);
882       hypre_SubtractBoxes(v_data_box, box, diff_boxes);
883 
884       vp = hypre_StructVectorBoxData(vector, i);
885       hypre_ForBoxI(j, diff_boxes)
886       {
887          diff_box = hypre_BoxArrayBox(diff_boxes, j);
888          start = hypre_BoxIMin(diff_box);
889 
890          hypre_BoxGetSize(diff_box, loop_size);
891 
892 #define DEVICE_VAR is_device_ptr(vp)
893          hypre_BoxLoop1Begin(hypre_StructVectorNDim(vector), loop_size,
894                              v_data_box, start, unit_stride, vi);
895          {
896             vp[vi] = 0.0;
897          }
898          hypre_BoxLoop1End(vi);
899 #undef DEVICE_VAR
900       }
901    }
902    hypre_BoxArrayDestroy(diff_boxes);
903 
904    return hypre_error_flag;
905 }
906 
907 /*--------------------------------------------------------------------------
908  * clears vector values on the physical boundaries
909  *--------------------------------------------------------------------------*/
910 
911 HYPRE_Int
hypre_StructVectorClearBoundGhostValues(hypre_StructVector * vector,HYPRE_Int force)912 hypre_StructVectorClearBoundGhostValues( hypre_StructVector *vector,
913                                          HYPRE_Int           force )
914 {
915    HYPRE_Int           ndim = hypre_StructVectorNDim(vector);
916    HYPRE_Complex      *vp;
917    hypre_BoxArray     *boxes;
918    hypre_Box          *box;
919    hypre_Box          *v_data_box;
920    hypre_Index         loop_size;
921    hypre_IndexRef      start;
922    hypre_Index         stride;
923    hypre_Box          *bbox;
924    hypre_StructGrid   *grid;
925    hypre_BoxArray     *boundary_boxes;
926    hypre_BoxArray     *array_of_box;
927    hypre_BoxArray     *work_boxarray;
928 
929    HYPRE_Int           i, i2;
930 
931    /*-----------------------------------------------------------------------
932     * Set the vector coefficients
933     *-----------------------------------------------------------------------*/
934 
935    /* Only clear if not clear already or if force argument is set */
936    if (hypre_StructVectorBGhostNotClear(vector) || force)
937    {
938       grid = hypre_StructVectorGrid(vector);
939       boxes = hypre_StructGridBoxes(grid);
940       hypre_SetIndex(stride, 1);
941 
942       hypre_ForBoxI(i, boxes)
943       {
944          box        = hypre_BoxArrayBox(boxes, i);
945          boundary_boxes = hypre_BoxArrayCreate( 0, ndim );
946          v_data_box =
947             hypre_BoxArrayBox(hypre_StructVectorDataSpace(vector), i);
948          hypre_BoxBoundaryG( v_data_box, grid, boundary_boxes );
949          vp = hypre_StructVectorBoxData(vector, i);
950 
951          /* box is a grid box, no ghost zones.
952             v_data_box is vector data box, may or may not have ghost zones
953             To get only ghost zones, subtract box from boundary_boxes.   */
954          work_boxarray = hypre_BoxArrayCreate( 0, ndim );
955          array_of_box = hypre_BoxArrayCreate( 1, ndim );
956          hypre_BoxArrayBoxes(array_of_box)[0] = *box;
957          hypre_SubtractBoxArrays( boundary_boxes, array_of_box, work_boxarray );
958 
959          hypre_ForBoxI(i2, boundary_boxes)
960          {
961             bbox       = hypre_BoxArrayBox(boundary_boxes, i2);
962             hypre_BoxGetSize(bbox, loop_size);
963             start = hypre_BoxIMin(bbox);
964 #define DEVICE_VAR is_device_ptr(vp)
965             hypre_BoxLoop1Begin(hypre_StructVectorNDim(vector), loop_size,
966                                 v_data_box, start, stride, vi);
967             {
968                vp[vi] = 0.0;
969             }
970             hypre_BoxLoop1End(vi);
971 #undef DEVICE_VAR
972          }
973          hypre_BoxArrayDestroy(boundary_boxes);
974          hypre_BoxArrayDestroy(work_boxarray);
975          hypre_BoxArrayDestroy(array_of_box);
976       }
977 
978       hypre_StructVectorBGhostNotClear(vector) = 0;
979    }
980 
981    return hypre_error_flag;
982 }
983 
984 /*--------------------------------------------------------------------------
985  *--------------------------------------------------------------------------*/
986 
987 HYPRE_Int
hypre_StructVectorScaleValues(hypre_StructVector * vector,HYPRE_Complex factor)988 hypre_StructVectorScaleValues( hypre_StructVector *vector, HYPRE_Complex factor )
989 {
990    HYPRE_Complex    *data;
991 
992    hypre_Index       imin;
993    hypre_Index       imax;
994    hypre_Box        *box;
995    hypre_Index       loop_size;
996 
997    /*-----------------------------------------------------------------------
998     * Set the vector coefficients
999     *-----------------------------------------------------------------------*/
1000 
1001    box = hypre_BoxCreate(hypre_StructVectorNDim(vector));
1002    hypre_SetIndex(imin, 1);
1003    hypre_SetIndex(imax, 1);
1004    hypre_IndexD(imax, 0) = hypre_StructVectorDataSize(vector);
1005    hypre_BoxSetExtents(box, imin, imax);
1006    data = hypre_StructVectorData(vector);
1007    hypre_BoxGetSize(box, loop_size);
1008 
1009 #define DEVICE_VAR is_device_ptr(data)
1010    hypre_BoxLoop1Begin(hypre_StructVectorNDim(vector), loop_size,
1011                        box, imin, imin, datai);
1012    {
1013       data[datai] *= factor;
1014    }
1015    hypre_BoxLoop1End(datai);
1016 #undef DEVICE_VAR
1017 
1018    hypre_BoxDestroy(box);
1019 
1020    return hypre_error_flag;
1021 }
1022 
1023 /*--------------------------------------------------------------------------
1024  *--------------------------------------------------------------------------*/
1025 
1026 hypre_CommPkg *
hypre_StructVectorGetMigrateCommPkg(hypre_StructVector * from_vector,hypre_StructVector * to_vector)1027 hypre_StructVectorGetMigrateCommPkg( hypre_StructVector *from_vector,
1028                                      hypre_StructVector *to_vector   )
1029 {
1030    hypre_CommInfo        *comm_info;
1031    hypre_CommPkg         *comm_pkg;
1032 
1033    /*------------------------------------------------------
1034     * Set up hypre_CommPkg
1035     *------------------------------------------------------*/
1036 
1037    hypre_CreateCommInfoFromGrids(hypre_StructVectorGrid(from_vector),
1038                                  hypre_StructVectorGrid(to_vector),
1039                                  &comm_info);
1040    hypre_CommPkgCreate(comm_info,
1041                        hypre_StructVectorDataSpace(from_vector),
1042                        hypre_StructVectorDataSpace(to_vector), 1, NULL, 0,
1043                        hypre_StructVectorComm(from_vector), &comm_pkg);
1044    hypre_CommInfoDestroy(comm_info);
1045    /* is this correct for periodic? */
1046 
1047    return comm_pkg;
1048 }
1049 
1050 /*--------------------------------------------------------------------------
1051  *--------------------------------------------------------------------------*/
1052 
1053 HYPRE_Int
hypre_StructVectorMigrate(hypre_CommPkg * comm_pkg,hypre_StructVector * from_vector,hypre_StructVector * to_vector)1054 hypre_StructVectorMigrate( hypre_CommPkg      *comm_pkg,
1055                            hypre_StructVector *from_vector,
1056                            hypre_StructVector *to_vector   )
1057 {
1058    hypre_CommHandle      *comm_handle;
1059 
1060    /*-----------------------------------------------------------------------
1061     * Migrate the vector data
1062     *-----------------------------------------------------------------------*/
1063 
1064    hypre_InitializeCommunication(comm_pkg,
1065                                  hypre_StructVectorData(from_vector),
1066                                  hypre_StructVectorData(to_vector), 0, 0,
1067                                  &comm_handle);
1068    hypre_FinalizeCommunication(comm_handle);
1069 
1070    return hypre_error_flag;
1071 }
1072 
1073 /*--------------------------------------------------------------------------
1074  * hypre_StructVectorPrint
1075  *--------------------------------------------------------------------------*/
1076 
1077 HYPRE_Int
hypre_StructVectorPrint(const char * filename,hypre_StructVector * vector,HYPRE_Int all)1078 hypre_StructVectorPrint( const char         *filename,
1079                          hypre_StructVector *vector,
1080                          HYPRE_Int           all      )
1081 {
1082    FILE              *file;
1083    char               new_filename[255];
1084 
1085    hypre_StructGrid  *grid;
1086    hypre_BoxArray    *boxes;
1087 
1088    hypre_BoxArray    *data_space;
1089 
1090    HYPRE_Int          myid;
1091 
1092    /*----------------------------------------
1093     * Open file
1094     *----------------------------------------*/
1095 
1096    hypre_MPI_Comm_rank(hypre_StructVectorComm(vector), &myid );
1097 
1098    hypre_sprintf(new_filename, "%s.%05d", filename, myid);
1099 
1100    if ((file = fopen(new_filename, "w")) == NULL)
1101    {
1102       hypre_printf("Error: can't open output file %s\n", new_filename);
1103       exit(1);
1104    }
1105 
1106    /*----------------------------------------
1107     * Print header info
1108     *----------------------------------------*/
1109 
1110    hypre_fprintf(file, "StructVector\n");
1111 
1112    /* print grid info */
1113    hypre_fprintf(file, "\nGrid:\n");
1114    grid = hypre_StructVectorGrid(vector);
1115    hypre_StructGridPrint(file, grid);
1116 
1117    /*----------------------------------------
1118     * Print data
1119     *----------------------------------------*/
1120 
1121    data_space = hypre_StructVectorDataSpace(vector);
1122 
1123    if (all)
1124       boxes = data_space;
1125    else
1126       boxes = hypre_StructGridBoxes(grid);
1127 
1128    hypre_fprintf(file, "\nData:\n");
1129    hypre_PrintBoxArrayData(file, boxes, data_space, 1,
1130                            hypre_StructGridNDim(grid),
1131                            hypre_StructVectorData(vector));
1132 
1133    /*----------------------------------------
1134     * Close file
1135     *----------------------------------------*/
1136 
1137    fflush(file);
1138    fclose(file);
1139 
1140    return hypre_error_flag;
1141 }
1142 
1143 /*--------------------------------------------------------------------------
1144  *--------------------------------------------------------------------------*/
1145 
1146 hypre_StructVector *
hypre_StructVectorRead(MPI_Comm comm,const char * filename,HYPRE_Int * num_ghost)1147 hypre_StructVectorRead( MPI_Comm    comm,
1148                         const char *filename,
1149                         HYPRE_Int  *num_ghost )
1150 {
1151    FILE                 *file;
1152    char                  new_filename[255];
1153 
1154    hypre_StructVector   *vector;
1155 
1156    hypre_StructGrid     *grid;
1157    hypre_BoxArray       *boxes;
1158 
1159    hypre_BoxArray       *data_space;
1160 
1161    HYPRE_Int             myid;
1162 
1163    /*----------------------------------------
1164     * Open file
1165     *----------------------------------------*/
1166 
1167    hypre_MPI_Comm_rank(comm, &myid );
1168 
1169    hypre_sprintf(new_filename, "%s.%05d", filename, myid);
1170 
1171    if ((file = fopen(new_filename, "r")) == NULL)
1172    {
1173       hypre_printf("Error: can't open output file %s\n", new_filename);
1174       exit(1);
1175    }
1176 
1177    /*----------------------------------------
1178     * Read header info
1179     *----------------------------------------*/
1180 
1181    hypre_fscanf(file, "StructVector\n");
1182 
1183    /* read grid info */
1184    hypre_fscanf(file, "\nGrid:\n");
1185    hypre_StructGridRead(comm,file,&grid);
1186 
1187    /*----------------------------------------
1188     * Initialize the vector
1189     *----------------------------------------*/
1190 
1191    vector = hypre_StructVectorCreate(comm, grid);
1192    hypre_StructVectorSetNumGhost(vector, num_ghost);
1193    hypre_StructVectorInitialize(vector);
1194 
1195    /*----------------------------------------
1196     * Read data
1197     *----------------------------------------*/
1198 
1199    boxes      = hypre_StructGridBoxes(grid);
1200    data_space = hypre_StructVectorDataSpace(vector);
1201 
1202    hypre_fscanf(file, "\nData:\n");
1203    hypre_ReadBoxArrayData(file, boxes, data_space, 1,
1204                           hypre_StructGridNDim(grid),
1205                           hypre_StructVectorData(vector));
1206 
1207    /*----------------------------------------
1208     * Assemble the vector
1209     *----------------------------------------*/
1210 
1211    hypre_StructVectorAssemble(vector);
1212 
1213    /*----------------------------------------
1214     * Close file
1215     *----------------------------------------*/
1216 
1217    fclose(file);
1218 
1219    return vector;
1220 }
1221 
1222 /*--------------------------------------------------------------------------
1223  * The following is used only as a debugging aid.
1224  *
1225  * hypre_StructVectorClone
1226  * Returns a complete copy of x - a deep copy, with its own copy of the data.
1227  *--------------------------------------------------------------------------*/
1228 hypre_StructVector *
hypre_StructVectorClone(hypre_StructVector * x)1229 hypre_StructVectorClone(hypre_StructVector *x)
1230 {
1231    MPI_Comm             comm = hypre_StructVectorComm(x);
1232    hypre_StructGrid    *grid = hypre_StructVectorGrid(x);
1233    hypre_BoxArray      *data_space = hypre_StructVectorDataSpace(x);
1234    HYPRE_Int           *data_indices = hypre_StructVectorDataIndices(x);
1235    HYPRE_Int            data_size = hypre_StructVectorDataSize(x);
1236    HYPRE_Int            ndim = hypre_StructGridNDim(grid);
1237    HYPRE_Int            data_space_size = hypre_BoxArraySize(data_space);
1238    HYPRE_Int            i;
1239    hypre_StructVector  *y = hypre_StructVectorCreate(comm, grid);
1240 
1241    hypre_StructVectorDataSize(y) = data_size;
1242    hypre_StructVectorDataSpace(y) = hypre_BoxArrayDuplicate(data_space);
1243    hypre_StructVectorData(y) =  hypre_CTAlloc(HYPRE_Complex,  data_size, HYPRE_MEMORY_DEVICE);
1244 
1245    hypre_StructVectorDataIndices(y) = hypre_CTAlloc(HYPRE_Int,  data_space_size, HYPRE_MEMORY_HOST);
1246 
1247    for (i=0; i < data_space_size; i++)
1248       hypre_StructVectorDataIndices(y)[i] = data_indices[i];
1249 
1250    hypre_StructVectorCopy( x, y );
1251 
1252    for (i=0; i < 2*ndim; i++)
1253       hypre_StructVectorNumGhost(y)[i] = hypre_StructVectorNumGhost(x)[i];
1254 
1255    hypre_StructVectorBGhostNotClear(y) = hypre_StructVectorBGhostNotClear(x);
1256    hypre_StructVectorGlobalSize(y) = hypre_StructVectorGlobalSize(x);
1257 
1258    return y;
1259 }
1260 
1261