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