30#include "fasp_functs.h"
36#include "PreAMGAggregation.inl"
37#include "PreAMGAggregationCSR.inl"
71 if ( prtlvl >
PRINT_NONE ) printf(
"\nSetting up SA AMG ...\n");
74 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
75 printf(
"### DEBUG: nr=%d, nc=%d, nnz=%d\n",
76 mgl[0].A.row, mgl[0].
A.
col, mgl[0].
A.
nnz);
80 status = amg_setup_smoothP_smoothR(mgl, param);
83 status = amg_setup_smoothP_unsmoothR(mgl, param);
87 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
115static void smooth_agg (
dCSRmat *A,
128 REAL row_sum_A, row_sum_N;
134 if ( filter !=
ON ) {
140#pragma omp parallel for if(row>OPENMP_HOLDS)
142 for ( i=0; i<=row; ++i ) S.
IA[i] = A->
IA[i];
143 for ( i=0; i<S.
IA[S.
row]; ++i ) S.
JA[i] = A->
JA[i];
150#pragma omp parallel for if(row>OPENMP_HOLDS)
152 for (i=0; i<row; ++i) {
153 if (
ABS(diag.
val[i]) < 1e-6) diag.
val[i] = 1.0;
157#pragma omp parallel for if(row>OPENMP_HOLDS) private(j)
159 for (i=0; i<row; ++i) {
160 for (j=S.
IA[i]; j<S.
IA[i+1]; ++j) {
162 S.
val[j] = 1 - smooth_factor * A->
val[j] / diag.
val[i];
165 S.
val[j] = - smooth_factor * A->
val[j] / diag.
val[i];
175#pragma omp parallel for private(j, row_sum_A, row_sum_N) if (row>OPENMP_HOLDS)
177 for (i=0; i<row; ++i) {
178 for (row_sum_A = 0.0, j=A->
IA[i]; j<A->IA[i+1]; ++j) {
179 if (A->
JA[j] != i) row_sum_A += A->
val[j];
182 for (row_sum_N = 0.0, j=N->
IA[i]; j<N->IA[i+1]; ++j) {
183 if (N->
JA[j] != i) row_sum_N += N->
val[j];
186 for (j=N->
IA[i]; j<N->IA[i+1]; ++j) {
189 N->
val[j] += row_sum_A - row_sum_N;
198#pragma omp parallel for if(row>OPENMP_HOLDS)
200 for (i=0; i<=row; ++i) S.
IA[i] = N->
IA[i];
202 for (i=0; i<S.
IA[S.
row]; ++i) S.
JA[i] = N->
JA[i];
209#pragma omp parallel for if(row>OPENMP_HOLDS)
211 for (i=0;i<row;++i) {
212 if (
ABS(diag.
val[i]) < 1e-6) diag.
val[i] = 1.0;
216#pragma omp parallel for if(row>OPENMP_HOLDS) private(i,j)
218 for (i=0;i<row;++i) {
219 for (j=S.
IA[i]; j<S.
IA[i+1]; ++j) {
221 S.
val[j] = 1 - smooth_factor * N->
val[j] / diag.
val[i];
224 S.
val[j] = - smooth_factor * N->
val[j] / diag.
val[i];
266 REAL setup_start, setup_end;
271 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
289 for ( i = 0; i < max_levels; ++i ) num_aggs[i] = 0;
296 for ( j = 0; j < m; ++j ) mgl[0].near_kernel_basis[i][j] = 1.0;
322 REAL lambda_max = 2.0, lambda_min = lambda_max/4;
337 while ( (mgl[lvl].A.
row > min_cdof) && (lvl < max_levels-1) ) {
340 printf(
"### DEBUG: level = %d, row = %d, nnz = %d\n",
341 lvl, mgl[lvl].A.
row, mgl[lvl].A.nnz);
345 if ( lvl < param->ILU_levels ) {
349 printf(
"### WARNING: ILU setup on level-%d failed!\n", lvl);
350 printf(
"### WARNING: Disable ILU for level >= %d.\n", lvl);
357 if ( lvl < param->SWZ_levels ) {
363 printf(
"### WARNING: Schwarz on level-%d failed!\n", lvl);
364 printf(
"### WARNING: Disable Schwarz for level >= %d.\n", lvl);
371 status = aggregation_vmb(&mgl[lvl].A, &vertices[lvl], param, lvl+1,
372 &Neighbor[lvl], &num_aggs[lvl]);
378 printf(
"### WARNING: Forming aggregates on level-%d failed!\n", lvl);
387 form_tentative_p(&vertices[lvl], &tentp[lvl], mgl[0].near_kernel_basis,
391 smooth_agg(&mgl[lvl].A, &tentp[lvl], &mgl[lvl].P, param, &Neighbor[lvl]);
404 printf(
"### WARNING: Coarsening might be too aggressive!\n");
405 printf(
"### WARNING: Fine level = %d, coarse level = %d. Discard!\n",
406 mgl[lvl].P.
row, mgl[lvl].P.col);
434 printf(
"### WARNING: Coarsening rate is too small!\n");
435 printf(
"### WARNING: Fine level = %d, coarse level = %d. Discard!\n",
436 mgl[lvl].P.
row, mgl[lvl].P.col);
467 mgl[lvl].
Numeric = fasp_umfpack_factorize(&mgl[lvl].A, 0);
475 fasp_pardiso_factorize(&mgl[lvl].A, &mgl[lvl].pdata, prtlvl);
489 for ( lvl = 1; lvl < max_levels; ++lvl) {
508 int threads = fasp_get_num_threads();
509 if (threads > max_levels-1 ) threads = max_levels-1;
510#pragma omp parallel for private(lvl,rowmax,Colors) schedule(static, 1) num_threads(threads)
512 for (lvl=0; lvl<max_levels-1; lvl++){
520 printf(
"mgl[%3d].A.row = %12d, rowmax = %5d, rowavg = %7.2lf, colors = %5d, Theta = %le.\n",
521 lvl, mgl[lvl].A.
row, rowmax, (
double)mgl[lvl].A.nnz/mgl[lvl].A.row,
522 mgl[lvl].A.color, mgl[lvl].GS_Theta);
529 fasp_cputime(
"Smoothed aggregation setup", setup_end - setup_start);
538 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
571 REAL setup_start, setup_end;
576 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
594 for ( i = 0; i < max_levels; ++i ) num_aggs[i] = 0;
602 for ( j = 0; j < m; ++j ) mgl[0].near_kernel_basis[i][j] = 1.0;
627 REAL lambda_max = 2.0, lambda_min = lambda_max/4;
632 while ( (mgl[lvl].A.
row > min_cdof) && (lvl < max_levels-1) ) {
635 if ( lvl < param->ILU_levels ) {
639 printf(
"### WARNING: ILU setup on level-%d failed!\n", lvl);
640 printf(
"### WARNING: Disable ILU for level >= %d.\n", lvl);
647 if ( lvl < param->SWZ_levels ) {
653 printf(
"### WARNING: Schwarz on level-%d failed!\n", lvl);
654 printf(
"### WARNING: Disable Schwarz for level >= %d.\n", lvl);
661 status = aggregation_vmb(&mgl[lvl].A, &vertices[lvl], param, lvl+1,
662 &Neighbor[lvl], &num_aggs[lvl]);
668 printf(
"### WARNING: Stop coarsening on level=%d!\n", lvl);
674 form_tentative_p(&vertices[lvl], &tentp[lvl], mgl[0].near_kernel_basis,
678 smooth_agg(&mgl[lvl].A, &tentp[lvl], &mgl[lvl].P, param, &Neighbor[lvl]);
686 printf(
"### WARNING: Coarsening might be too aggressive!\n");
687 printf(
"### WARNING: Fine level = %d, coarse level = %d. Discard!\n",
688 mgl[lvl].P.
row, mgl[lvl].P.col);
696 printf(
"### WARNING: Coarsening rate is too small!\n");
697 printf(
"### WARNING: Fine level = %d, coarse level = %d. Discard!\n",
698 mgl[lvl].P.
row, mgl[lvl].P.col);
740 mgl[lvl].
Numeric = fasp_umfpack_factorize(&mgl[lvl].A, 0);
748 fasp_pardiso_factorize(&mgl[lvl].A, &mgl[lvl].pdata, prtlvl);
762 for ( lvl = 1; lvl < max_levels; ++lvl) {
781 int threads = fasp_get_num_threads();
782 if (threads > max_levels-1 ) threads = max_levels-1;
783#pragma omp parallel for private(lvl,rowmax,Colors) schedule(static, 1) num_threads(threads)
785 for (lvl=0; lvl<max_levels-1; lvl++){
793 printf(
"mgl[%3d].A.row = %12d, rowmax = %5d, rowavg = %7.2lf, colors = %5d, Theta = %le.\n",
794 lvl, mgl[lvl].A.
row, rowmax, (
double)mgl[lvl].A.nnz/mgl[lvl].A.row,
795 mgl[lvl].A.color, mgl[lvl].GS_Theta);
802 fasp_cputime(
"Smoothed aggregation 1/2 setup", setup_end - setup_start);
812 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
void fasp_mem_free(void *mem)
Free up previous allocated memory body and set pointer to NULL.
void * fasp_mem_calloc(const unsigned int size, const unsigned int type)
Allocate, initiate, and check memory.
void fasp_cputime(const char *message, const REAL cputime)
Print CPU walltime.
void fasp_amgcomplexity(const AMG_data *mgl, const SHORT prtlvl)
Print level and complexity information of AMG.
void fasp_gettime(REAL *time)
Get system time.
void fasp_dvec_free(dvector *u)
Free vector data space of REAL type.
void fasp_ivec_free(ivector *u)
Free vector data space of INT type.
dvector fasp_dvec_create(const INT m)
Create dvector data space of REAL type.
SHORT fasp_ilu_dcsr_setup(dCSRmat *A, ILU_data *iludata, ILU_param *iluparam)
Get ILU decomposition of a CSR matrix A.
INT fasp_swz_dcsr_setup(SWZ_data *swzdata, SWZ_param *swzparam)
Setup phase for the Schwarz methods.
void fasp_dcsr_diagpref(dCSRmat *A)
Re-order the column and data arrays of a CSR matrix, so that the first entry in each row is the diago...
dCSRmat fasp_dcsr_create(const INT m, const INT n, const INT nnz)
Create CSR sparse matrix data memory space.
void fasp_dcsr_shift(dCSRmat *A, const INT offset)
Re-index a REAL matrix in CSR format to make the index starting from 0 or 1.
void dCSRmat_Multicoloring_Theta(dCSRmat *A, REAL theta, INT *rowmax, INT *groups)
Use the greedy multicoloring algorithm to get color groups for for the adjacency graph of A.
void fasp_dcsr_free(dCSRmat *A)
Free CSR sparse matrix data memory space.
void fasp_dcsr_transz(dCSRmat *A, INT *p, dCSRmat *AT)
Generalized transpose of A: (n x m) matrix given in dCSRmat format.
void fasp_dcsr_sort(dCSRmat *A)
Sort each row of A in ascending order w.r.t. column indices.
void dCSRmat_Multicoloring(dCSRmat *A, INT *rowmax, INT *groups)
Use the greedy multicoloring algorithm to get color groups for for the adjacency graph of A.
void fasp_dcsr_cp(const dCSRmat *A, dCSRmat *B)
copy a dCSRmat to a new one B=A
void fasp_dcsr_getdiag(INT n, const dCSRmat *A, dvector *diag)
Get first n diagonal entries of a CSR matrix A.
dCSRmat fasp_dcsr_sympart(dCSRmat *A)
Get symmetric part of a dCSRmat matrix.
INT fasp_dcsr_trans(const dCSRmat *A, dCSRmat *AT)
Find transpose of dCSRmat matrix A.
void fasp_blas_dcsr_mxm(const dCSRmat *A, const dCSRmat *B, dCSRmat *C)
Sparse matrix multiplication C=A*B.
void fasp_blas_dcsr_rap_agg(const dCSRmat *R, const dCSRmat *A, const dCSRmat *P, dCSRmat *RAP)
Triple sparse matrix multiplication B=R*A*P (nonzeros of R, P = 1)
void fasp_blas_dcsr_rap(const dCSRmat *R, const dCSRmat *A, const dCSRmat *P, dCSRmat *RAP)
Triple sparse matrix multiplication B=R*A*P.
SHORT fasp_amg_setup_sa(AMG_data *mgl, AMG_param *param)
Set up phase of smoothed aggregation AMG.
void fasp_amg_amli_coef(const REAL lambda_max, const REAL lambda_min, const INT degree, REAL *coef)
Compute the coefficients of the polynomial used by AMLI-cycle.
int fasp_solver_mumps_steps(dCSRmat *ptrA, dvector *b, dvector *u, Mumps_data *mumps)
Solve Ax=b by MUMPS in three steps.
Main header file for the FASP project.
#define SHORT
FASP integer and floating point numbers.
#define MAX(a, b)
Definition of max, min, abs.
#define FASP_SUCCESS
Definition of return status and error messages.
#define PAIRWISE
Definition of aggregation types.
#define ON
Definition of switch.
#define PRINT_NONE
Print level for all subroutines – not including DEBUG output.
INT near_kernel_dim
dimension of the near kernel for SAMG
dCSRmat A
pointer to the matrix at level level_num
Mumps_data mumps
data for MUMPS
SWZ_data Schwarz
data of Schwarz smoother
dvector b
pointer to the right-hand side at level level_num
REAL ** near_kernel_basis
basis of near kernel space for SAMG
void * Numeric
pointer to the numerical factorization from UMFPACK
INT ILU_levels
number of levels use ILU smoother
INT SWZ_levels
number of levels use Schwarz smoother
dvector x
pointer to the iterative solution at level level_num
SHORT num_levels
number of levels in use <= max_levels
dvector w
temporary work space
Parameters for AMG methods.
INT ILU_lfil
level of fill-in for ILUs and ILUk
REAL ILU_relax
relaxation for ILUs
INT SWZ_mmsize
maximal block size
SHORT print_level
print level for AMG
INT SWZ_maxlvl
maximal levels
SHORT aggregation_type
aggregation type
SHORT smooth_filter
switch for filtered matrix used for smoothing the tentative prolongation
REAL * amli_coef
coefficients of the polynomial used by AMLI cycle
SHORT ILU_levels
number of levels use ILU smoother
SHORT coarse_solver
coarse solver type
SHORT cycle_type
type of AMG cycle
SHORT amli_degree
degree of the polynomial used by AMLI cycle
SHORT ILU_type
ILU type for smoothing.
INT SWZ_blksolver
type of Schwarz block solver
INT SWZ_type
type of Schwarz method
INT coarse_dof
max number of coarsest level DOF
REAL ILU_droptol
drop tolerance for ILUt
REAL tentative_smooth
relaxation parameter for smoothing the tentative prolongation
INT SWZ_levels
number of levels use Schwarz smoother
INT pair_number
number of pairwise matchings
SHORT max_levels
max number of levels of AMG
SHORT smooth_restriction
smooth the restriction for SA methods or not
INT ILU_lfil
level of fill-in for ILUk
REAL ILU_relax
add the sum of dropped elements to diagonal element in proportion relax
SHORT print_level
print level
SHORT ILU_type
ILU type for decomposition.
REAL ILU_droptol
drop tolerance for ILUt
dCSRmat A
pointer to the original coefficient matrix
Parameters for Schwarz method.
INT SWZ_mmsize
maximal size of blocks
INT SWZ_maxlvl
maximal level for constructing the blocks
INT SWZ_blksolver
type of Schwarz block solver
SHORT SWZ_type
type for Schwarz method
Sparse matrix of REAL type in CSR format.
INT col
column of matrix A, n
REAL * val
nonzero entries of A
INT row
row number of matrix A, m
INT * IA
integer array of row pointers, the size is m+1
INT nnz
number of nonzero entries
INT * JA
integer array of column indexes, the size is nnz
Vector with n entries of REAL type.
REAL * val
actual vector entries
Vector with n entries of INT type.