Fast Auxiliary Space Preconditioning 2.7.7 Aug/28/2022
Loading...
Searching...
No Matches
PreAMGSetupUABSR.c
Go to the documentation of this file.
1
22#include <math.h>
23#include <time.h>
24
25#include "fasp.h"
26#include "fasp_functs.h"
27
28/*---------------------------------*/
29/*-- Declare Private Functions --*/
30/*---------------------------------*/
31
32#include "PreAMGAggregation.inl"
33#include "PreAMGAggregationBSR.inl"
34#include "PreAMGAggregationUA.inl"
35
36static SHORT amg_setup_unsmoothP_unsmoothR_bsr(AMG_data_bsr*, AMG_param*);
37
38/*---------------------------------*/
39/*-- Public Functions --*/
40/*---------------------------------*/
41
56{
57#if DEBUG_MODE > 0
58 printf("### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
59#endif
60
61 SHORT status = amg_setup_unsmoothP_unsmoothR_bsr(mgl, param);
62
63#if DEBUG_MODE > 0
64 printf("### DEBUG: [--End--] %s ...\n", __FUNCTION__);
65#endif
66
67 return status;
68}
69
70/*---------------------------------*/
71/*-- Private Functions --*/
72/*---------------------------------*/
73
91static SHORT amg_setup_unsmoothP_unsmoothR_bsr(AMG_data_bsr* mgl, AMG_param* param)
92{
93 const SHORT CondType = 2; // Condensation method used for AMG
94
95 const SHORT prtlvl = param->print_level;
96 const SHORT csolver = param->coarse_solver;
97 const SHORT min_cdof = MAX(param->coarse_dof, 50);
98 const INT m = mgl[0].A.ROW;
99 const INT nb = mgl[0].A.nb;
100
101 SHORT max_levels = param->max_levels;
102 SHORT i, lvl = 0, status = FASP_SUCCESS;
103 REAL setup_start, setup_end;
104
105 AMG_data* mgl_csr = fasp_amg_data_create(max_levels);
106
107 dCSRmat temp1, temp2;
108
109#if DEBUG_MODE > 0
110 printf("### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
111 printf("### DEBUG: nr=%d, nc=%d, nnz=%d\n", mgl[0].A.ROW, mgl[0].A.COL,
112 mgl[0].A.NNZ);
113#endif
114
115 fasp_gettime(&setup_start);
116
117 /*-----------------------*/
118 /*--local working array--*/
119 /*-----------------------*/
120
121 // level info (fine: 0; coarse: 1)
122 ivector* vertices = (ivector*)fasp_mem_calloc(max_levels, sizeof(ivector));
123
124 // each elvel stores the information of the number of aggregations
125 INT* num_aggs = (INT*)fasp_mem_calloc(max_levels, sizeof(INT));
126
127 // each level stores the information of the strongly coupled neighborhoods
128 dCSRmat* Neighbor = (dCSRmat*)fasp_mem_calloc(max_levels, sizeof(dCSRmat));
129
130 for (i = 0; i < max_levels; ++i) num_aggs[i] = 0;
131
132 /*------------------------------------------*/
133 /*-- setup null spaces for whole Jacobian --*/
134 /*------------------------------------------*/
135
136 /*
137 mgl[0].near_kernel_dim = 1;
138 mgl[0].near_kernel_basis = (REAL **)fasp_mem_calloc(mgl->near_kernel_dim,
139 sizeof(REAL*));
140
141 for ( i=0; i < mgl->near_kernel_dim; ++i ) mgl[0].near_kernel_basis[i] = NULL;
142 */
143
144 /*-----------------------*/
145 /*-- setup ILU param --*/
146 /*-----------------------*/
147
148 // initialize ILU parameters
149 mgl->ILU_levels = param->ILU_levels;
150 ILU_param iluparam;
151
152 if (param->ILU_levels > 0) {
153 iluparam.print_level = param->print_level;
154 iluparam.ILU_lfil = param->ILU_lfil;
155 iluparam.ILU_droptol = param->ILU_droptol;
156 iluparam.ILU_relax = param->ILU_relax;
157 iluparam.ILU_type = param->ILU_type;
158 }
159
160 /*----------------------------*/
161 /*--- checking aggregation ---*/
162 /*----------------------------*/
163 if (param->aggregation_type == PAIRWISE)
164 param->pair_number = MIN(param->pair_number, max_levels);
165
166 // Main AMG setup loop
167 while ((mgl[lvl].A.ROW > min_cdof) && (lvl < max_levels - 1)) {
168
169 /*-- setup ILU decomposition if necessary */
170 if (lvl < param->ILU_levels) {
171 status = fasp_ilu_dbsr_setup(&mgl[lvl].A, &mgl[lvl].LU, &iluparam);
172 if (status < 0) {
173 if (prtlvl > PRINT_MIN) {
174 printf("### WARNING: ILU setup on level-%d failed!\n", lvl);
175 printf("### WARNING: Disable ILU for level >= %d.\n", lvl);
176 }
177 param->ILU_levels = lvl;
178 }
179 }
180
181 /*-- get the diagonal inverse --*/
182 mgl[lvl].diaginv = fasp_dbsr_getdiaginv(&mgl[lvl].A);
183
184 switch (CondType) {
185 case 2:
186 mgl[lvl].PP = condenseBSR(&mgl[lvl].A);
187 break;
188 default:
189 mgl[lvl].PP = condenseBSRLinf(&mgl[lvl].A);
190 break;
191 }
192
193 /*-- Aggregation --*/
194 switch (param->aggregation_type) {
195
196 case VMB: // VMB aggregation
197
198 status = aggregation_vmb(&mgl[lvl].PP, &vertices[lvl], param, lvl + 1,
199 &Neighbor[lvl], &num_aggs[lvl]);
200
201 /*-- Choose strength threshold adaptively --*/
202 if (num_aggs[lvl] * 4 > mgl[lvl].PP.row)
203 // param->strong_coupled /= 4.0;
204 param->strong_coupled /= 8.0;
205 else if (num_aggs[lvl] * 1.25 < mgl[lvl].PP.row)
206 param->strong_coupled *= 1.5;
207
208 break;
209
210 case NPAIR: // non-symmetric pairwise matching aggregation
211
212 mgl_csr[lvl].A = mgl[lvl].PP;
213 status =
214 aggregation_nsympair(mgl_csr, param, lvl, vertices, &num_aggs[lvl]);
215
216 break;
217
218 default: // symmetric pairwise matching aggregation
219
220 mgl_csr[lvl].A = mgl[lvl].PP;
221 status =
222 aggregation_symmpair(mgl_csr, param, lvl, vertices, &num_aggs[lvl]);
223
224 // TODO: Need to design better algorithm for pairwise BSR -- Xiaozhe
225 // TODO: Unsymmetric pairwise aggregation not finished -- Chensong
226 // TODO: Check why this fails for BSR --Chensong
227
228 break;
229 }
230
231 if (status < 0) {
232 // When error happens, force solver to use the current multigrid levels!
233 if (prtlvl > PRINT_MIN) {
234 printf("### WARNING: Forming aggregates on level-%d failed!\n", lvl);
235 }
236 status = FASP_SUCCESS;
237 break;
238 }
239
240 /* -- Form Prolongation --*/
241 if (lvl == 0 && mgl[0].near_kernel_dim > 0) {
242 form_tentative_p_bsr1(&vertices[lvl], &mgl[lvl].P, &mgl[0], num_aggs[lvl],
243 mgl[0].near_kernel_dim, mgl[0].near_kernel_basis);
244 } else {
245 form_boolean_p_bsr(&vertices[lvl], &mgl[lvl].P, &mgl[0], num_aggs[lvl]);
246 }
247
248 /*-- Form resitriction --*/
249 fasp_dbsr_trans(&mgl[lvl].P, &mgl[lvl].R);
250
251 /*-- Form coarse level stiffness matrix --*/
252 fasp_blas_dbsr_rap(&mgl[lvl].R, &mgl[lvl].A, &mgl[lvl].P, &mgl[lvl + 1].A);
253
254 /* -- Form extra near kernal space if needed --*/
255 if (mgl[lvl].A_nk != NULL) {
256
257 mgl[lvl + 1].A_nk = (dCSRmat*)fasp_mem_calloc(1, sizeof(dCSRmat));
258 mgl[lvl + 1].P_nk = (dCSRmat*)fasp_mem_calloc(1, sizeof(dCSRmat));
259 mgl[lvl + 1].R_nk = (dCSRmat*)fasp_mem_calloc(1, sizeof(dCSRmat));
260
261 temp1 = fasp_format_dbsr_dcsr(&mgl[lvl].R);
262 fasp_blas_dcsr_mxm(&temp1, mgl[lvl].P_nk, mgl[lvl + 1].P_nk);
263 fasp_dcsr_trans(mgl[lvl + 1].P_nk, mgl[lvl + 1].R_nk);
264 temp2 = fasp_format_dbsr_dcsr(&mgl[lvl + 1].A);
265 fasp_blas_dcsr_rap(mgl[lvl + 1].R_nk, &temp2, mgl[lvl + 1].P_nk,
266 mgl[lvl + 1].A_nk);
267 fasp_dcsr_free(&temp1);
268 fasp_dcsr_free(&temp2);
269 }
270
271 fasp_dcsr_free(&Neighbor[lvl]);
272 fasp_ivec_free(&vertices[lvl]);
273
274 ++lvl;
275 }
276
277 // Setup coarse level systems for direct solvers (BSR version)
278 switch (csolver) {
279
280#if WITH_MUMPS
281 case SOLVER_MUMPS:
282 {
283 // Setup MUMPS direct solver on the coarsest level
284 mgl[lvl].Ac = fasp_format_dbsr_dcsr(&mgl[lvl].A);
285 mgl[lvl].mumps.job = 1;
286 fasp_solver_mumps_steps(&mgl[lvl].Ac, &mgl[lvl].b, &mgl[lvl].x,
287 &mgl[lvl].mumps);
288 break;
289 }
290#endif
291
292#if WITH_UMFPACK
293 case SOLVER_UMFPACK:
294 {
295 // Need to sort the matrix A for UMFPACK to work
296 mgl[lvl].Ac = fasp_format_dbsr_dcsr(&mgl[lvl].A);
297 dCSRmat Ac_tran;
298 fasp_dcsr_trans(&mgl[lvl].Ac, &Ac_tran);
299 fasp_dcsr_sort(&Ac_tran);
300 fasp_dcsr_cp(&Ac_tran, &mgl[lvl].Ac);
301 fasp_dcsr_free(&Ac_tran);
302 mgl[lvl].Numeric = fasp_umfpack_factorize(&mgl[lvl].Ac, 0);
303 break;
304 }
305#endif
306
307#if WITH_SuperLU
308 case SOLVER_SUPERLU:
309 {
310 /* Setup SuperLU direct solver on the coarsest level */
311 mgl[lvl].Ac = fasp_format_dbsr_dcsr(&mgl[lvl].A);
312 }
313#endif
314
315#if WITH_PARDISO
316 case SOLVER_PARDISO:
317 {
318 mgl[lvl].Ac = fasp_format_dbsr_dcsr(&mgl[lvl].A);
319 fasp_dcsr_sort(&mgl[lvl].Ac);
320 fasp_pardiso_factorize(&mgl[lvl].Ac, &mgl[lvl].pdata, prtlvl);
321 break;
322 }
323#endif
324
325 default:
326 // Do nothing!
327 break;
328 }
329
330 // setup total level number and current level
331 mgl[0].num_levels = max_levels = lvl + 1;
332 mgl[0].w = fasp_dvec_create(3 * m * nb);
333
334 if (mgl[0].A_nk != NULL) {
335
336#if WITH_UMFPACK
337 // Need to sort the matrix A_nk for UMFPACK
338 fasp_dcsr_trans(mgl[0].A_nk, &temp1);
339 fasp_dcsr_sort(&temp1);
340 fasp_dcsr_cp(&temp1, mgl[0].A_nk);
341 fasp_dcsr_free(&temp1);
342#endif
343 }
344
345 for (lvl = 1; lvl < max_levels; lvl++) {
346 const INT mm = mgl[lvl].A.ROW * nb;
347 mgl[lvl].num_levels = max_levels;
348 mgl[lvl].b = fasp_dvec_create(mm);
349 mgl[lvl].x = fasp_dvec_create(mm);
350 mgl[lvl].w = fasp_dvec_create(3 * mm);
351 mgl[lvl].ILU_levels = param->ILU_levels - lvl; // initialize ILU levels!
352
353 if (mgl[lvl].A_nk != NULL) {
354
355#if WITH_UMFPACK
356 // Need to sort the matrix A_nk for UMFPACK
357 fasp_dcsr_trans(mgl[lvl].A_nk, &temp1);
358 fasp_dcsr_sort(&temp1);
359 fasp_dcsr_cp(&temp1, mgl[lvl].A_nk);
360 fasp_dcsr_free(&temp1);
361#endif
362 }
363 }
364
365 if (prtlvl > PRINT_NONE) {
366 fasp_gettime(&setup_end);
367 fasp_amgcomplexity_bsr(mgl, prtlvl);
368 fasp_cputime("Unsmoothed aggregation (BSR) setup", setup_end - setup_start);
369 }
370
371 fasp_mem_free(vertices);
372 vertices = NULL;
373 fasp_mem_free(num_aggs);
374 num_aggs = NULL;
375 fasp_mem_free(Neighbor);
376 Neighbor = NULL;
377
378#if DEBUG_MODE > 0
379 printf("### DEBUG: [--End--] %s ...\n", __FUNCTION__);
380#endif
381
382 return status;
383}
384
385/*---------------------------------*/
386/*-- End of File --*/
387/*---------------------------------*/
void fasp_mem_free(void *mem)
Free up previous allocated memory body and set pointer to NULL.
Definition: AuxMemory.c:152
void * fasp_mem_calloc(const unsigned int size, const unsigned int type)
Allocate, initiate, and check memory.
Definition: AuxMemory.c:65
void fasp_cputime(const char *message, const REAL cputime)
Print CPU walltime.
Definition: AuxMessage.c:179
void fasp_amgcomplexity_bsr(const AMG_data_bsr *mgl, const SHORT prtlvl)
Print complexities of AMG method for BSR matrices.
Definition: AuxMessage.c:136
void fasp_gettime(REAL *time)
Get system time.
Definition: AuxTiming.c:37
void fasp_ivec_free(ivector *u)
Free vector data space of INT type.
Definition: AuxVector.c:164
dvector fasp_dvec_create(const INT m)
Create dvector data space of REAL type.
Definition: AuxVector.c:62
dCSRmat fasp_format_dbsr_dcsr(const dBSRmat *B)
Transfer a 'dBSRmat' type matrix into a dCSRmat.
Definition: BlaFormat.c:497
SHORT fasp_ilu_dbsr_setup(dBSRmat *A, ILU_data *iludata, ILU_param *iluparam)
Get ILU decoposition of a BSR matrix A.
INT fasp_dbsr_trans(const dBSRmat *A, dBSRmat *AT)
Find A^T from given dBSRmat matrix A.
Definition: BlaSparseBSR.c:246
dvector fasp_dbsr_getdiaginv(const dBSRmat *A)
Get D^{-1} of matrix A.
Definition: BlaSparseBSR.c:543
void fasp_dcsr_free(dCSRmat *A)
Free CSR sparse matrix data memory space.
Definition: BlaSparseCSR.c:184
void fasp_dcsr_sort(dCSRmat *A)
Sort each row of A in ascending order w.r.t. column indices.
Definition: BlaSparseCSR.c:385
void fasp_dcsr_cp(const dCSRmat *A, dCSRmat *B)
copy a dCSRmat to a new one B=A
Definition: BlaSparseCSR.c:851
INT fasp_dcsr_trans(const dCSRmat *A, dCSRmat *AT)
Find transpose of dCSRmat matrix A.
Definition: BlaSparseCSR.c:952
void fasp_blas_dbsr_rap(const dBSRmat *R, const dBSRmat *A, const dBSRmat *P, dBSRmat *B)
dBSRmat sparse matrix multiplication B=R*A*P
Definition: BlaSpmvBSR.c:5466
void fasp_blas_dcsr_mxm(const dCSRmat *A, const dCSRmat *B, dCSRmat *C)
Sparse matrix multiplication C=A*B.
Definition: BlaSpmvCSR.c:893
void fasp_blas_dcsr_rap(const dCSRmat *R, const dCSRmat *A, const dCSRmat *P, dCSRmat *RAP)
Triple sparse matrix multiplication B=R*A*P.
Definition: BlaSpmvCSR.c:999
SHORT fasp_amg_setup_ua_bsr(AMG_data_bsr *mgl, AMG_param *param)
Set up phase of unsmoothed aggregation AMG (BSR format)
AMG_data * fasp_amg_data_create(SHORT max_levels)
Create and initialize AMG_data for classical and SA AMG.
Definition: PreDataInit.c:64
int fasp_solver_mumps_steps(dCSRmat *ptrA, dvector *b, dvector *u, Mumps_data *mumps)
Solve Ax=b by MUMPS in three steps.
Definition: XtrMumps.c:196
Main header file for the FASP project.
#define MIN(a, b)
Definition: fasp.h:83
#define REAL
Definition: fasp.h:75
#define SHORT
FASP integer and floating point numbers.
Definition: fasp.h:71
#define MAX(a, b)
Definition of max, min, abs.
Definition: fasp.h:82
#define INT
Definition: fasp.h:72
#define SOLVER_PARDISO
Definition: fasp_const.h:126
#define FASP_SUCCESS
Definition of return status and error messages.
Definition: fasp_const.h:19
#define NPAIR
Definition: fasp_const.h:172
#define SOLVER_MUMPS
Definition: fasp_const.h:125
#define PAIRWISE
Definition of aggregation types.
Definition: fasp_const.h:170
#define SOLVER_SUPERLU
Definition: fasp_const.h:123
#define SOLVER_UMFPACK
Definition: fasp_const.h:124
#define VMB
Definition: fasp_const.h:171
#define PRINT_NONE
Print level for all subroutines – not including DEBUG output.
Definition: fasp_const.h:73
#define PRINT_MIN
Definition: fasp_const.h:74
Data for multigrid levels in dBSRmat format.
Definition: fasp_block.h:146
dCSRmat PP
pointer to the pressure block (only for reservoir simulation)
Definition: fasp_block.h:182
dBSRmat A
pointer to the matrix at level level_num
Definition: fasp_block.h:155
dCSRmat * A_nk
Matrix data for near kernal.
Definition: fasp_block.h:232
dCSRmat Ac
pointer to the matrix at level level_num (csr format)
Definition: fasp_block.h:173
Mumps_data mumps
data for MUMPS
Definition: fasp_block.h:245
dvector b
pointer to the right-hand side at level level_num
Definition: fasp_block.h:164
void * Numeric
pointer to the numerical dactorization from UMFPACK
Definition: fasp_block.h:176
INT ILU_levels
number of levels use ILU smoother
Definition: fasp_block.h:217
INT num_levels
number of levels in use <= max_levels
Definition: fasp_block.h:152
dCSRmat * R_nk
Resriction for near kernal.
Definition: fasp_block.h:238
dvector x
pointer to the iterative solution at level level_num
Definition: fasp_block.h:167
dCSRmat * P_nk
Prolongation for near kernal.
Definition: fasp_block.h:235
dvector diaginv
pointer to the diagonal inverse at level level_num
Definition: fasp_block.h:170
dvector w
temporary work space
Definition: fasp_block.h:242
Data for AMG methods.
Definition: fasp.h:804
dCSRmat A
pointer to the matrix at level level_num
Definition: fasp.h:817
Parameters for AMG methods.
Definition: fasp.h:455
INT ILU_lfil
level of fill-in for ILUs and ILUk
Definition: fasp.h:566
REAL ILU_relax
relaxation for ILUs
Definition: fasp.h:572
SHORT print_level
print level for AMG
Definition: fasp.h:461
SHORT aggregation_type
aggregation type
Definition: fasp.h:518
SHORT ILU_levels
number of levels use ILU smoother
Definition: fasp.h:560
SHORT coarse_solver
coarse solver type
Definition: fasp.h:500
REAL strong_coupled
strong coupled threshold for aggregate
Definition: fasp.h:545
SHORT ILU_type
ILU type for smoothing.
Definition: fasp.h:563
INT coarse_dof
max number of coarsest level DOF
Definition: fasp.h:473
REAL ILU_droptol
drop tolerance for ILUt
Definition: fasp.h:569
INT pair_number
number of pairwise matchings
Definition: fasp.h:542
SHORT max_levels
max number of levels of AMG
Definition: fasp.h:470
Parameters for ILU.
Definition: fasp.h:404
INT ILU_lfil
level of fill-in for ILUk
Definition: fasp.h:413
REAL ILU_relax
add the sum of dropped elements to diagonal element in proportion relax
Definition: fasp.h:419
SHORT print_level
print level
Definition: fasp.h:407
SHORT ILU_type
ILU type for decomposition.
Definition: fasp.h:410
REAL ILU_droptol
drop tolerance for ILUt
Definition: fasp.h:416
INT job
work for MUMPS
Definition: fasp.h:615
INT nb
dimension of each sub-block
Definition: fasp_block.h:46
INT ROW
number of rows of sub-blocks in matrix A, M
Definition: fasp_block.h:37
Sparse matrix of REAL type in CSR format.
Definition: fasp.h:151
Vector with n entries of INT type.
Definition: fasp.h:368