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 #include "_hypre_struct_ls.h"
9
10 /*--------------------------------------------------------------------------
11 *--------------------------------------------------------------------------*/
12
13 typedef struct
14 {
15 HYPRE_Int setup_temp_vec;
16 HYPRE_Int setup_a_rem;
17 HYPRE_Int setup_a_sol;
18
19 MPI_Comm comm;
20
21 HYPRE_Int memory_use;
22 HYPRE_Real tol;
23 HYPRE_Int max_iter;
24 HYPRE_Int zero_guess;
25
26 HYPRE_Int num_spaces;
27 HYPRE_Int *space_indices;
28 HYPRE_Int *space_strides;
29
30 HYPRE_Int num_pre_spaces;
31 HYPRE_Int num_reg_spaces;
32 HYPRE_Int *pre_space_ranks;
33 HYPRE_Int *reg_space_ranks;
34
35 hypre_Index base_index;
36 hypre_Index base_stride;
37 hypre_BoxArray *base_box_array;
38
39 HYPRE_Int stencil_dim;
40
41 hypre_StructMatrix *A;
42 hypre_StructVector *b;
43 hypre_StructVector *x;
44
45 hypre_StructVector *temp_vec;
46 hypre_StructMatrix *A_sol; /* Coefficients of A that make up
47 the (sol)ve part of the relaxation */
48 hypre_StructMatrix *A_rem; /* Coefficients of A (rem)aining:
49 A_rem = A - A_sol */
50 void **residual_data; /* Array of size `num_spaces' */
51 void **solve_data; /* Array of size `num_spaces' */
52
53 /* log info (always logged) */
54 HYPRE_Int num_iterations;
55 HYPRE_Int time_index;
56
57 HYPRE_Int num_pre_relax;
58 HYPRE_Int num_post_relax;
59
60 HYPRE_Int max_level;
61 } hypre_SMGRelaxData;
62
63 /*--------------------------------------------------------------------------
64 *--------------------------------------------------------------------------*/
65
66 void *
hypre_SMGRelaxCreate(MPI_Comm comm)67 hypre_SMGRelaxCreate( MPI_Comm comm )
68 {
69 hypre_SMGRelaxData *relax_data;
70
71 relax_data = hypre_CTAlloc(hypre_SMGRelaxData, 1, HYPRE_MEMORY_HOST);
72 (relax_data -> setup_temp_vec) = 1;
73 (relax_data -> setup_a_rem) = 1;
74 (relax_data -> setup_a_sol) = 1;
75 (relax_data -> comm) = comm;
76 (relax_data -> base_box_array) = NULL;
77 (relax_data -> time_index) = hypre_InitializeTiming("SMGRelax");
78 /* set defaults */
79 (relax_data -> memory_use) = 0;
80 (relax_data -> tol) = 1.0e-06;
81 (relax_data -> max_iter) = 1000;
82 (relax_data -> zero_guess) = 0;
83 (relax_data -> num_spaces) = 1;
84 (relax_data -> space_indices) = hypre_TAlloc(HYPRE_Int, 1, HYPRE_MEMORY_HOST);
85 (relax_data -> space_strides) = hypre_TAlloc(HYPRE_Int, 1, HYPRE_MEMORY_HOST);
86 (relax_data -> space_indices[0]) = 0;
87 (relax_data -> space_strides[0]) = 1;
88 (relax_data -> num_pre_spaces) = 0;
89 (relax_data -> num_reg_spaces) = 1;
90 (relax_data -> pre_space_ranks) = NULL;
91 (relax_data -> reg_space_ranks) = hypre_TAlloc(HYPRE_Int, 1, HYPRE_MEMORY_HOST);
92 (relax_data -> reg_space_ranks[0]) = 0;
93 hypre_SetIndex3((relax_data -> base_index), 0, 0, 0);
94 hypre_SetIndex3((relax_data -> base_stride), 1, 1, 1);
95 (relax_data -> A) = NULL;
96 (relax_data -> b) = NULL;
97 (relax_data -> x) = NULL;
98 (relax_data -> temp_vec) = NULL;
99
100 (relax_data -> num_pre_relax) = 1;
101 (relax_data -> num_post_relax) = 1;
102 (relax_data -> max_level) = -1;
103 return (void *) relax_data;
104 }
105
106 /*--------------------------------------------------------------------------
107 *--------------------------------------------------------------------------*/
108
109 HYPRE_Int
hypre_SMGRelaxDestroyTempVec(void * relax_vdata)110 hypre_SMGRelaxDestroyTempVec( void *relax_vdata )
111 {
112 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
113
114 hypre_StructVectorDestroy(relax_data -> temp_vec);
115 (relax_data -> setup_temp_vec) = 1;
116
117 return hypre_error_flag;
118 }
119
120 /*--------------------------------------------------------------------------
121 *--------------------------------------------------------------------------*/
122
123 HYPRE_Int
hypre_SMGRelaxDestroyARem(void * relax_vdata)124 hypre_SMGRelaxDestroyARem( void *relax_vdata )
125 {
126 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
127 HYPRE_Int i;
128
129 if (relax_data -> A_rem)
130 {
131 for (i = 0; i < (relax_data -> num_spaces); i++)
132 {
133 hypre_SMGResidualDestroy(relax_data -> residual_data[i]);
134 }
135 hypre_TFree(relax_data -> residual_data, HYPRE_MEMORY_HOST);
136 hypre_StructMatrixDestroy(relax_data -> A_rem);
137 (relax_data -> A_rem) = NULL;
138 }
139 (relax_data -> setup_a_rem) = 1;
140
141 return hypre_error_flag;
142 }
143
144 /*--------------------------------------------------------------------------
145 *--------------------------------------------------------------------------*/
146
147 HYPRE_Int
hypre_SMGRelaxDestroyASol(void * relax_vdata)148 hypre_SMGRelaxDestroyASol( void *relax_vdata )
149 {
150 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
151 HYPRE_Int stencil_dim;
152 HYPRE_Int i;
153
154 if (relax_data -> A_sol)
155 {
156 stencil_dim = (relax_data -> stencil_dim);
157 for (i = 0; i < (relax_data -> num_spaces); i++)
158 {
159 if (stencil_dim > 2)
160 hypre_SMGDestroy(relax_data -> solve_data[i]);
161 else
162 hypre_CyclicReductionDestroy(relax_data -> solve_data[i]);
163 }
164 hypre_TFree(relax_data -> solve_data, HYPRE_MEMORY_HOST);
165 hypre_StructMatrixDestroy(relax_data -> A_sol);
166 (relax_data -> A_sol) = NULL;
167 }
168 (relax_data -> setup_a_sol) = 1;
169
170 return hypre_error_flag;
171 }
172
173 /*--------------------------------------------------------------------------
174 *--------------------------------------------------------------------------*/
175
176 HYPRE_Int
hypre_SMGRelaxDestroy(void * relax_vdata)177 hypre_SMGRelaxDestroy( void *relax_vdata )
178 {
179 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
180
181 if (relax_data)
182 {
183 hypre_TFree(relax_data -> space_indices, HYPRE_MEMORY_HOST);
184 hypre_TFree(relax_data -> space_strides, HYPRE_MEMORY_HOST);
185 hypre_TFree(relax_data -> pre_space_ranks, HYPRE_MEMORY_HOST);
186 hypre_TFree(relax_data -> reg_space_ranks, HYPRE_MEMORY_HOST);
187 hypre_BoxArrayDestroy(relax_data -> base_box_array);
188
189 hypre_StructMatrixDestroy(relax_data -> A);
190 hypre_StructVectorDestroy(relax_data -> b);
191 hypre_StructVectorDestroy(relax_data -> x);
192
193 hypre_SMGRelaxDestroyTempVec(relax_vdata);
194 hypre_SMGRelaxDestroyARem(relax_vdata);
195 hypre_SMGRelaxDestroyASol(relax_vdata);
196
197 hypre_FinalizeTiming(relax_data -> time_index);
198 hypre_TFree(relax_data, HYPRE_MEMORY_HOST);
199 }
200
201 return hypre_error_flag;
202 }
203
204 /*--------------------------------------------------------------------------
205 *--------------------------------------------------------------------------*/
206
207 HYPRE_Int
hypre_SMGRelax(void * relax_vdata,hypre_StructMatrix * A,hypre_StructVector * b,hypre_StructVector * x)208 hypre_SMGRelax( void *relax_vdata,
209 hypre_StructMatrix *A,
210 hypre_StructVector *b,
211 hypre_StructVector *x )
212 {
213 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
214
215 HYPRE_Int zero_guess;
216 HYPRE_Int stencil_dim;
217 hypre_StructVector *temp_vec;
218 hypre_StructMatrix *A_sol;
219 hypre_StructMatrix *A_rem;
220 void **residual_data;
221 void **solve_data;
222
223 hypre_IndexRef base_stride;
224 hypre_BoxArray *base_box_a;
225 HYPRE_Real zero = 0.0;
226
227 HYPRE_Int max_iter;
228 HYPRE_Int num_spaces;
229 HYPRE_Int *space_ranks;
230
231 HYPRE_Int i, j, k, is;
232
233 /*----------------------------------------------------------
234 * Note: The zero_guess stuff is not handled correctly
235 * for general relaxation parameters. It is correct when
236 * the spaces are independent sets in the direction of
237 * relaxation.
238 *----------------------------------------------------------*/
239
240 hypre_BeginTiming(relax_data -> time_index);
241
242 /*----------------------------------------------------------
243 * Set up the solver
244 *----------------------------------------------------------*/
245
246 /* insure that the solver memory gets fully set up */
247 if ((relax_data -> setup_a_sol) > 0)
248 {
249 (relax_data -> setup_a_sol) = 2;
250 }
251
252 hypre_SMGRelaxSetup(relax_vdata, A, b, x);
253
254 zero_guess = (relax_data -> zero_guess);
255 stencil_dim = (relax_data -> stencil_dim);
256 temp_vec = (relax_data -> temp_vec);
257 A_sol = (relax_data -> A_sol);
258 A_rem = (relax_data -> A_rem);
259 residual_data = (relax_data -> residual_data);
260 solve_data = (relax_data -> solve_data);
261
262 /*----------------------------------------------------------
263 * Set zero values
264 *----------------------------------------------------------*/
265
266 if (zero_guess)
267 {
268 base_stride = (relax_data -> base_stride);
269 base_box_a = (relax_data -> base_box_array);
270 hypre_SMGSetStructVectorConstantValues(x, zero, base_box_a, base_stride);
271 }
272
273 /*----------------------------------------------------------
274 * Iterate
275 *----------------------------------------------------------*/
276
277 for (k = 0; k < 2; k++)
278 {
279 switch(k)
280 {
281 /* Do pre-relaxation iterations */
282 case 0:
283 max_iter = 1;
284 num_spaces = (relax_data -> num_pre_spaces);
285 space_ranks = (relax_data -> pre_space_ranks);
286 break;
287
288 /* Do regular relaxation iterations */
289 case 1:
290 max_iter = (relax_data -> max_iter);
291 num_spaces = (relax_data -> num_reg_spaces);
292 space_ranks = (relax_data -> reg_space_ranks);
293 break;
294 }
295
296 for (i = 0; i < max_iter; i++)
297 {
298 for (j = 0; j < num_spaces; j++)
299 {
300 is = space_ranks[j];
301
302 hypre_SMGResidual(residual_data[is], A_rem, x, b, temp_vec);
303
304 if (stencil_dim > 2)
305 {
306 hypre_SMGSolve(solve_data[is], A_sol, temp_vec, x);
307 }
308 else
309 {
310 hypre_CyclicReduction(solve_data[is], A_sol, temp_vec, x);
311 }
312 }
313
314 (relax_data -> num_iterations) = (i + 1);
315 }
316 }
317
318 /*----------------------------------------------------------
319 * Free up memory according to memory_use parameter
320 *----------------------------------------------------------*/
321
322 if ((stencil_dim - 1) <= (relax_data -> memory_use))
323 {
324 hypre_SMGRelaxDestroyASol(relax_vdata);
325 }
326
327 hypre_EndTiming(relax_data -> time_index);
328
329 return hypre_error_flag;
330 }
331
332 /*--------------------------------------------------------------------------
333 *--------------------------------------------------------------------------*/
334
335 HYPRE_Int
hypre_SMGRelaxSetup(void * relax_vdata,hypre_StructMatrix * A,hypre_StructVector * b,hypre_StructVector * x)336 hypre_SMGRelaxSetup( void *relax_vdata,
337 hypre_StructMatrix *A,
338 hypre_StructVector *b,
339 hypre_StructVector *x )
340 {
341 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
342 HYPRE_Int stencil_dim;
343 HYPRE_Int a_sol_test;
344
345 stencil_dim = hypre_StructStencilNDim(hypre_StructMatrixStencil(A));
346 (relax_data -> stencil_dim) = stencil_dim;
347 hypre_StructMatrixDestroy(relax_data -> A);
348 hypre_StructVectorDestroy(relax_data -> b);
349 hypre_StructVectorDestroy(relax_data -> x);
350 (relax_data -> A) = hypre_StructMatrixRef(A);
351 (relax_data -> b) = hypre_StructVectorRef(b);
352 (relax_data -> x) = hypre_StructVectorRef(x);
353
354 /*----------------------------------------------------------
355 * Set up memory according to memory_use parameter.
356 *
357 * If a subset of the solver memory is not to be set up
358 * until the solve is actually done, it's "setup" tag
359 * should have a value greater than 1.
360 *----------------------------------------------------------*/
361
362 if ((stencil_dim - 1) <= (relax_data -> memory_use))
363 {
364 a_sol_test = 1;
365 }
366 else
367 {
368 a_sol_test = 0;
369 }
370
371 /*----------------------------------------------------------
372 * Set up the solver
373 *----------------------------------------------------------*/
374
375 if ((relax_data -> setup_temp_vec) > 0)
376 {
377 hypre_SMGRelaxSetupTempVec(relax_vdata, A, b, x);
378 }
379
380 if ((relax_data -> setup_a_rem) > 0)
381 {
382 hypre_SMGRelaxSetupARem(relax_vdata, A, b, x);
383 }
384
385 if ((relax_data -> setup_a_sol) > a_sol_test)
386 {
387 hypre_SMGRelaxSetupASol(relax_vdata, A, b, x);
388 }
389
390 if ((relax_data -> base_box_array) == NULL)
391 {
392 hypre_SMGRelaxSetupBaseBoxArray(relax_vdata, A, b, x);
393 }
394
395
396 return hypre_error_flag;
397 }
398
399 /*--------------------------------------------------------------------------
400 *--------------------------------------------------------------------------*/
401
402 HYPRE_Int
hypre_SMGRelaxSetupTempVec(void * relax_vdata,hypre_StructMatrix * A,hypre_StructVector * b,hypre_StructVector * x)403 hypre_SMGRelaxSetupTempVec( void *relax_vdata,
404 hypre_StructMatrix *A,
405 hypre_StructVector *b,
406 hypre_StructVector *x )
407 {
408 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
409 hypre_StructVector *temp_vec = (relax_data -> temp_vec);
410
411 /*----------------------------------------------------------
412 * Set up data
413 *----------------------------------------------------------*/
414
415 if ((relax_data -> temp_vec) == NULL)
416 {
417 temp_vec = hypre_StructVectorCreate(hypre_StructVectorComm(b),
418 hypre_StructVectorGrid(b));
419 hypre_StructVectorSetNumGhost(temp_vec, hypre_StructVectorNumGhost(b));
420 hypre_StructVectorInitialize(temp_vec);
421 hypre_StructVectorAssemble(temp_vec);
422 (relax_data -> temp_vec) = temp_vec;
423 }
424 (relax_data -> setup_temp_vec) = 0;
425
426 return hypre_error_flag;
427 }
428
429 /*--------------------------------------------------------------------------
430 * hypre_SMGRelaxSetupARem
431 *--------------------------------------------------------------------------*/
432
433 HYPRE_Int
hypre_SMGRelaxSetupARem(void * relax_vdata,hypre_StructMatrix * A,hypre_StructVector * b,hypre_StructVector * x)434 hypre_SMGRelaxSetupARem( void *relax_vdata,
435 hypre_StructMatrix *A,
436 hypre_StructVector *b,
437 hypre_StructVector *x )
438 {
439 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
440
441 HYPRE_Int num_spaces = (relax_data -> num_spaces);
442 HYPRE_Int *space_indices = (relax_data -> space_indices);
443 HYPRE_Int *space_strides = (relax_data -> space_strides);
444 hypre_StructVector *temp_vec = (relax_data -> temp_vec);
445
446 hypre_StructStencil *stencil = hypre_StructMatrixStencil(A);
447 hypre_Index *stencil_shape = hypre_StructStencilShape(stencil);
448 HYPRE_Int stencil_size = hypre_StructStencilSize(stencil);
449 HYPRE_Int stencil_dim = hypre_StructStencilNDim(stencil);
450
451 hypre_StructMatrix *A_rem;
452 void **residual_data;
453
454 hypre_Index base_index;
455 hypre_Index base_stride;
456
457 HYPRE_Int num_stencil_indices;
458 HYPRE_Int *stencil_indices;
459
460 HYPRE_Int i;
461
462 /*----------------------------------------------------------
463 * Free up old data before putting new data into structure
464 *----------------------------------------------------------*/
465
466 hypre_SMGRelaxDestroyARem(relax_vdata);
467
468 /*----------------------------------------------------------
469 * Set up data
470 *----------------------------------------------------------*/
471
472 hypre_CopyIndex((relax_data -> base_index), base_index);
473 hypre_CopyIndex((relax_data -> base_stride), base_stride);
474
475 stencil_indices = hypre_TAlloc(HYPRE_Int, stencil_size, HYPRE_MEMORY_HOST);
476 num_stencil_indices = 0;
477 for (i = 0; i < stencil_size; i++)
478 {
479 if (hypre_IndexD(stencil_shape[i], (stencil_dim - 1)) != 0)
480 {
481 stencil_indices[num_stencil_indices] = i;
482 num_stencil_indices++;
483 }
484 }
485 A_rem = hypre_StructMatrixCreateMask(A, num_stencil_indices, stencil_indices);
486 hypre_TFree(stencil_indices, HYPRE_MEMORY_HOST);
487
488 /* Set up residual_data */
489 residual_data = hypre_TAlloc(void *, num_spaces, HYPRE_MEMORY_HOST);
490
491 for (i = 0; i < num_spaces; i++)
492 {
493 hypre_IndexD(base_index, (stencil_dim - 1)) = space_indices[i];
494 hypre_IndexD(base_stride, (stencil_dim - 1)) = space_strides[i];
495
496 residual_data[i] = hypre_SMGResidualCreate();
497 hypre_SMGResidualSetBase(residual_data[i], base_index, base_stride);
498 hypre_SMGResidualSetup(residual_data[i], A_rem, x, b, temp_vec);
499 }
500
501 (relax_data -> A_rem) = A_rem;
502 (relax_data -> residual_data) = residual_data;
503
504 (relax_data -> setup_a_rem) = 0;
505
506 return hypre_error_flag;
507 }
508
509 /*--------------------------------------------------------------------------
510 *--------------------------------------------------------------------------*/
511
512 HYPRE_Int
hypre_SMGRelaxSetupASol(void * relax_vdata,hypre_StructMatrix * A,hypre_StructVector * b,hypre_StructVector * x)513 hypre_SMGRelaxSetupASol( void *relax_vdata,
514 hypre_StructMatrix *A,
515 hypre_StructVector *b,
516 hypre_StructVector *x )
517 {
518 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
519
520 HYPRE_Int num_spaces = (relax_data -> num_spaces);
521 HYPRE_Int *space_indices = (relax_data -> space_indices);
522 HYPRE_Int *space_strides = (relax_data -> space_strides);
523 hypre_StructVector *temp_vec = (relax_data -> temp_vec);
524
525 HYPRE_Int num_pre_relax = (relax_data -> num_pre_relax);
526 HYPRE_Int num_post_relax = (relax_data -> num_post_relax);
527
528 hypre_StructStencil *stencil = hypre_StructMatrixStencil(A);
529 hypre_Index *stencil_shape = hypre_StructStencilShape(stencil);
530 HYPRE_Int stencil_size = hypre_StructStencilSize(stencil);
531 HYPRE_Int stencil_dim = hypre_StructStencilNDim(stencil);
532
533 hypre_StructMatrix *A_sol;
534 void **solve_data;
535
536 hypre_Index base_index;
537 hypre_Index base_stride;
538
539 HYPRE_Int num_stencil_indices;
540 HYPRE_Int *stencil_indices;
541
542 HYPRE_Int i;
543
544 /*----------------------------------------------------------
545 * Free up old data before putting new data into structure
546 *----------------------------------------------------------*/
547
548 hypre_SMGRelaxDestroyASol(relax_vdata);
549
550 /*----------------------------------------------------------
551 * Set up data
552 *----------------------------------------------------------*/
553
554 hypre_CopyIndex((relax_data -> base_index), base_index);
555 hypre_CopyIndex((relax_data -> base_stride), base_stride);
556
557 stencil_indices = hypre_TAlloc(HYPRE_Int, stencil_size, HYPRE_MEMORY_HOST);
558 num_stencil_indices = 0;
559 for (i = 0; i < stencil_size; i++)
560 {
561 if (hypre_IndexD(stencil_shape[i], (stencil_dim - 1)) == 0)
562 {
563 stencil_indices[num_stencil_indices] = i;
564 num_stencil_indices++;
565 }
566 }
567
568 A_sol = hypre_StructMatrixCreateMask(A, num_stencil_indices, stencil_indices);
569 hypre_StructStencilNDim(hypre_StructMatrixStencil(A_sol)) = stencil_dim - 1;
570 hypre_TFree(stencil_indices, HYPRE_MEMORY_HOST);
571
572 /* Set up solve_data */
573 solve_data = hypre_TAlloc(void *, num_spaces, HYPRE_MEMORY_HOST);
574
575 for (i = 0; i < num_spaces; i++)
576 {
577 hypre_IndexD(base_index, (stencil_dim - 1)) = space_indices[i];
578 hypre_IndexD(base_stride, (stencil_dim - 1)) = space_strides[i];
579
580 if (stencil_dim > 2)
581 {
582 solve_data[i] = hypre_SMGCreate(relax_data -> comm);
583 hypre_SMGSetNumPreRelax( solve_data[i], num_pre_relax);
584 hypre_SMGSetNumPostRelax( solve_data[i], num_post_relax);
585 hypre_SMGSetBase(solve_data[i], base_index, base_stride);
586 hypre_SMGSetMemoryUse(solve_data[i], (relax_data -> memory_use));
587 hypre_SMGSetTol(solve_data[i], 0.0);
588 hypre_SMGSetMaxIter(solve_data[i], 1);
589 hypre_StructSMGSetMaxLevel(solve_data[i], (relax_data -> max_level));
590 hypre_SMGSetup(solve_data[i], A_sol, temp_vec, x);
591 }
592 else
593 {
594 solve_data[i] = hypre_CyclicReductionCreate(relax_data -> comm);
595 hypre_CyclicReductionSetBase(solve_data[i], base_index, base_stride);
596 //hypre_CyclicReductionSetMaxLevel(solve_data[i], -1);//(relax_data -> max_level)+10);
597 hypre_CyclicReductionSetup(solve_data[i], A_sol, temp_vec, x);
598 }
599 }
600
601 (relax_data -> A_sol) = A_sol;
602 (relax_data -> solve_data) = solve_data;
603
604 (relax_data -> setup_a_sol) = 0;
605
606 return hypre_error_flag;
607 }
608
609 /*--------------------------------------------------------------------------
610 *--------------------------------------------------------------------------*/
611
612 HYPRE_Int
hypre_SMGRelaxSetTempVec(void * relax_vdata,hypre_StructVector * temp_vec)613 hypre_SMGRelaxSetTempVec( void *relax_vdata,
614 hypre_StructVector *temp_vec )
615 {
616 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
617
618 hypre_SMGRelaxDestroyTempVec(relax_vdata);
619 (relax_data -> temp_vec) = hypre_StructVectorRef(temp_vec);
620
621 (relax_data -> setup_temp_vec) = 1;
622 (relax_data -> setup_a_rem) = 1;
623 (relax_data -> setup_a_sol) = 1;
624
625 return hypre_error_flag;
626 }
627
628 /*--------------------------------------------------------------------------
629 *--------------------------------------------------------------------------*/
630
631 HYPRE_Int
hypre_SMGRelaxSetMemoryUse(void * relax_vdata,HYPRE_Int memory_use)632 hypre_SMGRelaxSetMemoryUse( void *relax_vdata,
633 HYPRE_Int memory_use )
634 {
635 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
636
637 (relax_data -> memory_use) = memory_use;
638
639 return hypre_error_flag;
640 }
641
642 /*--------------------------------------------------------------------------
643 *--------------------------------------------------------------------------*/
644
645 HYPRE_Int
hypre_SMGRelaxSetTol(void * relax_vdata,HYPRE_Real tol)646 hypre_SMGRelaxSetTol( void *relax_vdata,
647 HYPRE_Real tol )
648 {
649 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
650
651 (relax_data -> tol) = tol;
652
653 return hypre_error_flag;
654 }
655
656 /*--------------------------------------------------------------------------
657 *--------------------------------------------------------------------------*/
658
659 HYPRE_Int
hypre_SMGRelaxSetMaxIter(void * relax_vdata,HYPRE_Int max_iter)660 hypre_SMGRelaxSetMaxIter( void *relax_vdata,
661 HYPRE_Int max_iter )
662 {
663 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
664
665 (relax_data -> max_iter) = max_iter;
666
667 return hypre_error_flag;
668 }
669
670 /*--------------------------------------------------------------------------
671 *--------------------------------------------------------------------------*/
672
673 HYPRE_Int
hypre_SMGRelaxSetZeroGuess(void * relax_vdata,HYPRE_Int zero_guess)674 hypre_SMGRelaxSetZeroGuess( void *relax_vdata,
675 HYPRE_Int zero_guess )
676 {
677 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
678
679 (relax_data -> zero_guess) = zero_guess;
680
681 return hypre_error_flag;
682 }
683
684 /*--------------------------------------------------------------------------
685 *--------------------------------------------------------------------------*/
686
687 HYPRE_Int
hypre_SMGRelaxSetNumSpaces(void * relax_vdata,HYPRE_Int num_spaces)688 hypre_SMGRelaxSetNumSpaces( void *relax_vdata,
689 HYPRE_Int num_spaces )
690 {
691 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
692 HYPRE_Int i;
693
694 (relax_data -> num_spaces) = num_spaces;
695
696 hypre_TFree(relax_data -> space_indices, HYPRE_MEMORY_HOST);
697 hypre_TFree(relax_data -> space_strides, HYPRE_MEMORY_HOST);
698 hypre_TFree(relax_data -> pre_space_ranks, HYPRE_MEMORY_HOST);
699 hypre_TFree(relax_data -> reg_space_ranks, HYPRE_MEMORY_HOST);
700 (relax_data -> space_indices) = hypre_TAlloc(HYPRE_Int, num_spaces, HYPRE_MEMORY_HOST);
701 (relax_data -> space_strides) = hypre_TAlloc(HYPRE_Int, num_spaces, HYPRE_MEMORY_HOST);
702 (relax_data -> num_pre_spaces) = 0;
703 (relax_data -> num_reg_spaces) = num_spaces;
704 (relax_data -> pre_space_ranks) = NULL;
705 (relax_data -> reg_space_ranks) = hypre_TAlloc(HYPRE_Int, num_spaces, HYPRE_MEMORY_HOST);
706
707 for (i = 0; i < num_spaces; i++)
708 {
709 (relax_data -> space_indices[i]) = 0;
710 (relax_data -> space_strides[i]) = 1;
711 (relax_data -> reg_space_ranks[i]) = i;
712 }
713
714 (relax_data -> setup_temp_vec) = 1;
715 (relax_data -> setup_a_rem) = 1;
716 (relax_data -> setup_a_sol) = 1;
717
718 return hypre_error_flag;
719 }
720
721 /*--------------------------------------------------------------------------
722 *--------------------------------------------------------------------------*/
723
724 HYPRE_Int
hypre_SMGRelaxSetNumPreSpaces(void * relax_vdata,HYPRE_Int num_pre_spaces)725 hypre_SMGRelaxSetNumPreSpaces( void *relax_vdata,
726 HYPRE_Int num_pre_spaces )
727 {
728 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
729 HYPRE_Int i;
730
731 (relax_data -> num_pre_spaces) = num_pre_spaces;
732
733 hypre_TFree(relax_data -> pre_space_ranks, HYPRE_MEMORY_HOST);
734 (relax_data -> pre_space_ranks) = hypre_TAlloc(HYPRE_Int, num_pre_spaces, HYPRE_MEMORY_HOST);
735
736 for (i = 0; i < num_pre_spaces; i++)
737 (relax_data -> pre_space_ranks[i]) = 0;
738
739 return hypre_error_flag;
740 }
741
742 /*--------------------------------------------------------------------------
743 *--------------------------------------------------------------------------*/
744
745 HYPRE_Int
hypre_SMGRelaxSetNumRegSpaces(void * relax_vdata,HYPRE_Int num_reg_spaces)746 hypre_SMGRelaxSetNumRegSpaces( void *relax_vdata,
747 HYPRE_Int num_reg_spaces )
748 {
749 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
750 HYPRE_Int i;
751
752 (relax_data -> num_reg_spaces) = num_reg_spaces;
753
754 hypre_TFree(relax_data -> reg_space_ranks, HYPRE_MEMORY_HOST);
755 (relax_data -> reg_space_ranks) = hypre_TAlloc(HYPRE_Int, num_reg_spaces, HYPRE_MEMORY_HOST);
756
757 for (i = 0; i < num_reg_spaces; i++)
758 (relax_data -> reg_space_ranks[i]) = 0;
759
760 return hypre_error_flag;
761 }
762
763 /*--------------------------------------------------------------------------
764 *--------------------------------------------------------------------------*/
765
766 HYPRE_Int
hypre_SMGRelaxSetSpace(void * relax_vdata,HYPRE_Int i,HYPRE_Int space_index,HYPRE_Int space_stride)767 hypre_SMGRelaxSetSpace( void *relax_vdata,
768 HYPRE_Int i,
769 HYPRE_Int space_index,
770 HYPRE_Int space_stride )
771 {
772 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
773
774 (relax_data -> space_indices[i]) = space_index;
775 (relax_data -> space_strides[i]) = space_stride;
776
777 (relax_data -> setup_temp_vec) = 1;
778 (relax_data -> setup_a_rem) = 1;
779 (relax_data -> setup_a_sol) = 1;
780
781 return hypre_error_flag;
782 }
783
784 /*--------------------------------------------------------------------------
785 *--------------------------------------------------------------------------*/
786
787 HYPRE_Int
hypre_SMGRelaxSetRegSpaceRank(void * relax_vdata,HYPRE_Int i,HYPRE_Int reg_space_rank)788 hypre_SMGRelaxSetRegSpaceRank( void *relax_vdata,
789 HYPRE_Int i,
790 HYPRE_Int reg_space_rank )
791 {
792 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
793
794 (relax_data -> reg_space_ranks[i]) = reg_space_rank;
795
796 return hypre_error_flag;
797 }
798
799 /*--------------------------------------------------------------------------
800 *--------------------------------------------------------------------------*/
801
802 HYPRE_Int
hypre_SMGRelaxSetPreSpaceRank(void * relax_vdata,HYPRE_Int i,HYPRE_Int pre_space_rank)803 hypre_SMGRelaxSetPreSpaceRank( void *relax_vdata,
804 HYPRE_Int i,
805 HYPRE_Int pre_space_rank )
806 {
807 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
808
809 (relax_data -> pre_space_ranks[i]) = pre_space_rank;
810
811 return hypre_error_flag;
812 }
813
814 /*--------------------------------------------------------------------------
815 *--------------------------------------------------------------------------*/
816
817 HYPRE_Int
hypre_SMGRelaxSetBase(void * relax_vdata,hypre_Index base_index,hypre_Index base_stride)818 hypre_SMGRelaxSetBase( void *relax_vdata,
819 hypre_Index base_index,
820 hypre_Index base_stride )
821 {
822 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
823 HYPRE_Int d;
824
825 for (d = 0; d < 3; d++)
826 {
827 hypre_IndexD((relax_data -> base_index), d) =
828 hypre_IndexD(base_index, d);
829 hypre_IndexD((relax_data -> base_stride), d) =
830 hypre_IndexD(base_stride, d);
831 }
832
833 if ((relax_data -> base_box_array) != NULL)
834 {
835 hypre_BoxArrayDestroy((relax_data -> base_box_array));
836 (relax_data -> base_box_array) = NULL;
837 }
838
839 (relax_data -> setup_temp_vec) = 1;
840 (relax_data -> setup_a_rem) = 1;
841 (relax_data -> setup_a_sol) = 1;
842
843 return hypre_error_flag;
844 }
845
846 /*--------------------------------------------------------------------------
847 * Note that we require at least 1 pre-relax sweep.
848 *--------------------------------------------------------------------------*/
849
850 HYPRE_Int
hypre_SMGRelaxSetNumPreRelax(void * relax_vdata,HYPRE_Int num_pre_relax)851 hypre_SMGRelaxSetNumPreRelax( void *relax_vdata,
852 HYPRE_Int num_pre_relax )
853 {
854 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
855
856 (relax_data -> num_pre_relax) = hypre_max(num_pre_relax,1);
857
858 return hypre_error_flag;
859 }
860
861 /*--------------------------------------------------------------------------
862 *--------------------------------------------------------------------------*/
863
864 HYPRE_Int
hypre_SMGRelaxSetNumPostRelax(void * relax_vdata,HYPRE_Int num_post_relax)865 hypre_SMGRelaxSetNumPostRelax( void *relax_vdata,
866 HYPRE_Int num_post_relax )
867 {
868 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
869
870 (relax_data -> num_post_relax) = num_post_relax;
871
872 return hypre_error_flag;
873 }
874
875 /*--------------------------------------------------------------------------
876 *--------------------------------------------------------------------------*/
877
878 HYPRE_Int
hypre_SMGRelaxSetNewMatrixStencil(void * relax_vdata,hypre_StructStencil * diff_stencil)879 hypre_SMGRelaxSetNewMatrixStencil( void *relax_vdata,
880 hypre_StructStencil *diff_stencil )
881 {
882 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
883
884 hypre_Index *stencil_shape = hypre_StructStencilShape(diff_stencil);
885 HYPRE_Int stencil_size = hypre_StructStencilSize(diff_stencil);
886 HYPRE_Int stencil_dim = hypre_StructStencilNDim(diff_stencil);
887
888 HYPRE_Int i;
889
890 for (i = 0; i < stencil_size; i++)
891 {
892 if (hypre_IndexD(stencil_shape[i], (stencil_dim - 1)) != 0)
893 {
894 (relax_data -> setup_a_rem) = 1;
895 }
896 else
897 {
898 (relax_data -> setup_a_sol) = 1;
899 }
900 }
901
902 return hypre_error_flag;
903 }
904
905
906 /*--------------------------------------------------------------------------
907 * hypre_SMGRelaxSetupBaseBoxArray
908 *--------------------------------------------------------------------------*/
909
910 HYPRE_Int
hypre_SMGRelaxSetupBaseBoxArray(void * relax_vdata,hypre_StructMatrix * A,hypre_StructVector * b,hypre_StructVector * x)911 hypre_SMGRelaxSetupBaseBoxArray( void *relax_vdata,
912 hypre_StructMatrix *A,
913 hypre_StructVector *b,
914 hypre_StructVector *x )
915 {
916 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
917
918 hypre_StructGrid *grid;
919 hypre_BoxArray *boxes;
920 hypre_BoxArray *base_box_array;
921
922 grid = hypre_StructVectorGrid(x);
923 boxes = hypre_StructGridBoxes(grid);
924
925 base_box_array = hypre_BoxArrayDuplicate(boxes);
926 hypre_ProjectBoxArray(base_box_array,
927 (relax_data -> base_index),
928 (relax_data -> base_stride));
929
930 (relax_data -> base_box_array) = base_box_array;
931
932 return hypre_error_flag;
933 }
934
935 /*--------------------------------------------------------------------------
936 *--------------------------------------------------------------------------*/
937
938 HYPRE_Int
hypre_SMGRelaxSetMaxLevel(void * relax_vdata,HYPRE_Int num_max_level)939 hypre_SMGRelaxSetMaxLevel( void *relax_vdata,
940 HYPRE_Int num_max_level )
941 {
942 hypre_SMGRelaxData *relax_data = (hypre_SMGRelaxData *)relax_vdata;
943
944 (relax_data -> max_level) = num_max_level;
945
946 return hypre_error_flag;
947 }
948