30#include "fasp_functs.h"
79 const INT MIN_ITER = 0;
87 const REAL cr_max = 0.99;
88 const REAL cr_min = 0.174;
92 INT restart1 = restart + 1;
95 REAL r_norm, r_normb, gamma, t;
100 REAL r_norm_old = 0.0;
102 INT restart_max = restart;
104 INT Restart = restart;
110 REAL *c = NULL, *s = NULL, *rs = NULL;
111 REAL *norms = NULL, *r = NULL, *w = NULL;
112 REAL *work = NULL, *x_best = NULL;
113 REAL **p = NULL, **hh = NULL;
116 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling Safe VGMRes solver (CSR) ...\n");
119 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
120 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
127 while ( (work == NULL) && (restart > 5 ) ) {
128 restart = restart - 5 ;
130 printf(
"### WARNING: vGMRES restart number set to %d!\n", restart);
131 restart1 = restart + 1;
134 if ( work == NULL ) {
135 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__);
143 r = work; w = r + n; rs = w + n; c = rs + restart1;
144 x_best = c + restart; s = x_best + n;
146 for ( i = 0; i < restart1; i++ ) p[i] = s + restart + i*n;
148 for ( i = 0; i < restart1; i++ ) hh[i] = p[restart] + n + i*restart;
160 relres = r_norm/normr0;
169 relres = r_normb/normr0;
174 relres = normr0/normu;
177 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
182 if ( relres < tol )
goto FINISHED;
191 while ( iter < MaxIt ) {
193 rs[0] = r_norm_old = r_norm;
202 if ( cr > cr_max || iter == 0 ) {
203 Restart = restart_max;
205 else if ( cr < cr_min ) {
209 if ( Restart - d > restart_min ) {
213 Restart = restart_max;
219 while ( i < Restart && iter < MaxIt ) {
232 for (j = 0; j < i; j ++) {
243 for (j = 1; j < i; ++j) {
245 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
246 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
248 t= hh[i][i-1]*hh[i][i-1];
249 t+= hh[i-1][i-1]*hh[i-1][i-1];
252 if (gamma == 0.0) gamma = epsmac;
253 c[i-1] = hh[i-1][i-1] / gamma;
254 s[i-1] = hh[i][i-1] / gamma;
255 rs[i] = -s[i-1]*rs[i-1];
256 rs[i-1] = c[i-1]*rs[i-1];
257 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
259 absres = r_norm = fabs(rs[i]);
261 relres = absres/normr0;
263 norms[iter] = relres;
266 fasp_itinfo(PrtLvl, StopType, iter, relres, absres,
267 norms[iter]/norms[iter-1]);
270 if ( relres <= tol && iter >= MIN_ITER )
break;
275 rs[i-1] = rs[i-1] / hh[i-1][i-1];
276 for (k = i-2; k >= 0; k --) {
278 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
281 rs[k] = t / hh[k][k];
302 goto RESTORE_BESTSOL;
305 if ( absres < absres_best - maxdiff) {
306 absres_best = absres;
312 if ( relres <= tol && iter >= MIN_ITER ) {
319 switch ( StopType ) {
322 relres = absres/normr0;
330 relres = absres/normr0;
335 relres = absres/normu;
339 norms[iter] = relres;
341 if ( relres <= tol ) {
352 for ( j = i; j > 0; j-- ) {
353 rs[j-1] = -s[j-1]*rs[j];
354 rs[j] = c[j-1]*rs[j];
369 cr = r_norm / r_norm_old;
374 if ( iter != iter_best ) {
380 switch ( StopType ) {
397 if ( absres > absres_best + maxdiff || isnan(absres) ) {
398 if ( PrtLvl >
PRINT_NONE ) ITS_RESTORE(iter_best);
400 relres = absres_best / normr0;
405 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,relres);
416 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
456 const SHORT StopType,
460 const INT MIN_ITER = 0;
468 const REAL cr_max = 0.99;
469 const REAL cr_min = 0.174;
473 INT restart1 = restart + 1;
476 REAL r_norm, r_normb, gamma, t;
481 REAL r_norm_old = 0.0;
483 INT restart_max = restart;
485 INT Restart = restart;
491 REAL *c = NULL, *s = NULL, *rs = NULL;
492 REAL *norms = NULL, *r = NULL, *w = NULL;
493 REAL *work = NULL, *x_best = NULL;
494 REAL **p = NULL, **hh = NULL;
497 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling Safe VGMRes solver (BSR) ...\n");
500 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
501 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
508 while ( (work == NULL) && (restart > 5 ) ) {
509 restart = restart - 5 ;
511 printf(
"### WARNING: vGMRES restart number set to %d!\n", restart);
512 restart1 = restart + 1;
515 if ( work == NULL ) {
516 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__);
524 r = work; w = r + n; rs = w + n; c = rs + restart1;
525 x_best = c + restart; s = x_best + n;
527 for ( i = 0; i < restart1; i++ ) p[i] = s + restart + i*n;
529 for ( i = 0; i < restart1; i++ ) hh[i] = p[restart] + n + i*restart;
541 relres = r_norm/normr0;
550 relres = r_normb/normr0;
555 relres = normr0/normu;
558 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
563 if ( relres < tol )
goto FINISHED;
572 while ( iter < MaxIt ) {
574 rs[0] = r_norm_old = r_norm;
583 if ( cr > cr_max || iter == 0 ) {
584 Restart = restart_max;
586 else if ( cr < cr_min ) {
590 if ( Restart - d > restart_min ) {
594 Restart = restart_max;
600 while ( i < Restart && iter < MaxIt ) {
613 for (j = 0; j < i; j ++) {
624 for (j = 1; j < i; ++j) {
626 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
627 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
629 t= hh[i][i-1]*hh[i][i-1];
630 t+= hh[i-1][i-1]*hh[i-1][i-1];
633 if (gamma == 0.0) gamma = epsmac;
634 c[i-1] = hh[i-1][i-1] / gamma;
635 s[i-1] = hh[i][i-1] / gamma;
636 rs[i] = -s[i-1]*rs[i-1];
637 rs[i-1] = c[i-1]*rs[i-1];
638 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
640 absres = r_norm = fabs(rs[i]);
642 relres = absres/normr0;
644 norms[iter] = relres;
647 fasp_itinfo(PrtLvl, StopType, iter, relres, absres,
648 norms[iter]/norms[iter-1]);
651 if ( relres <= tol && iter >= MIN_ITER )
break;
656 rs[i-1] = rs[i-1] / hh[i-1][i-1];
657 for (k = i-2; k >= 0; k --) {
659 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
662 rs[k] = t / hh[k][k];
683 goto RESTORE_BESTSOL;
686 if ( absres < absres_best - maxdiff) {
687 absres_best = absres;
693 if ( relres <= tol && iter >= MIN_ITER ) {
700 switch ( StopType ) {
703 relres = absres/normr0;
711 relres = absres/normr0;
716 relres = absres/normu;
720 norms[iter] = relres;
722 if ( relres <= tol ) {
733 for ( j = i; j > 0; j-- ) {
734 rs[j-1] = -s[j-1]*rs[j];
735 rs[j] = c[j-1]*rs[j];
750 cr = r_norm / r_norm_old;
755 if ( iter != iter_best ) {
761 switch ( StopType ) {
778 if ( absres > absres_best + maxdiff || isnan(absres) ) {
779 if ( PrtLvl >
PRINT_NONE ) ITS_RESTORE(iter_best);
781 relres = absres_best / normr0;
786 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,relres);
797 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
836 const SHORT StopType,
840 const INT MIN_ITER = 0;
848 const REAL cr_max = 0.99;
849 const REAL cr_min = 0.174;
853 INT restart1 = restart + 1;
856 REAL r_norm, r_normb, gamma, t;
861 REAL r_norm_old = 0.0;
863 INT restart_max = restart;
865 INT Restart = restart;
871 REAL *c = NULL, *s = NULL, *rs = NULL;
872 REAL *norms = NULL, *r = NULL, *w = NULL;
873 REAL *work = NULL, *x_best = NULL;
874 REAL **p = NULL, **hh = NULL;
877 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling Safe VGMRes solver (BLC) ...\n");
880 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
881 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
888 while ( (work == NULL) && (restart > 5 ) ) {
889 restart = restart - 5 ;
891 printf(
"### WARNING: vGMRES restart number set to %d!\n", restart);
892 restart1 = restart + 1;
895 if ( work == NULL ) {
896 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__);
904 r = work; w = r + n; rs = w + n; c = rs + restart1;
905 x_best = c + restart; s = x_best + n;
907 for ( i = 0; i < restart1; i++ ) p[i] = s + restart + i*n;
909 for ( i = 0; i < restart1; i++ ) hh[i] = p[restart] + n + i*restart;
921 relres = r_norm/normr0;
930 relres = r_normb/normr0;
935 relres = normr0/normu;
938 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
943 if ( relres < tol )
goto FINISHED;
952 while ( iter < MaxIt ) {
954 rs[0] = r_norm_old = r_norm;
963 if ( cr > cr_max || iter == 0 ) {
964 Restart = restart_max;
966 else if ( cr < cr_min ) {
970 if ( Restart - d > restart_min ) {
974 Restart = restart_max;
980 while ( i < Restart && iter < MaxIt ) {
993 for (j = 0; j < i; j ++) {
1004 for (j = 1; j < i; ++j) {
1006 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
1007 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
1009 t= hh[i][i-1]*hh[i][i-1];
1010 t+= hh[i-1][i-1]*hh[i-1][i-1];
1013 if (gamma == 0.0) gamma = epsmac;
1014 c[i-1] = hh[i-1][i-1] / gamma;
1015 s[i-1] = hh[i][i-1] / gamma;
1016 rs[i] = -s[i-1]*rs[i-1];
1017 rs[i-1] = c[i-1]*rs[i-1];
1018 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
1020 absres = r_norm = fabs(rs[i]);
1022 relres = absres/normr0;
1024 norms[iter] = relres;
1027 fasp_itinfo(PrtLvl, StopType, iter, relres, absres,
1028 norms[iter]/norms[iter-1]);
1031 if ( relres <= tol && iter >= MIN_ITER )
break;
1036 rs[i-1] = rs[i-1] / hh[i-1][i-1];
1037 for (k = i-2; k >= 0; k --) {
1039 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
1042 rs[k] = t / hh[k][k];
1063 goto RESTORE_BESTSOL;
1066 if ( absres < absres_best - maxdiff) {
1067 absres_best = absres;
1073 if ( relres <= tol && iter >= MIN_ITER ) {
1080 switch ( StopType ) {
1083 relres = absres/normr0;
1091 relres = absres/normr0;
1096 relres = absres/normu;
1100 norms[iter] = relres;
1102 if ( relres <= tol ) {
1113 for ( j = i; j > 0; j-- ) {
1114 rs[j-1] = -s[j-1]*rs[j];
1115 rs[j] = c[j-1]*rs[j];
1130 cr = r_norm / r_norm_old;
1135 if ( iter != iter_best ) {
1141 switch ( StopType ) {
1158 if ( absres > absres_best + maxdiff || isnan(absres) ) {
1159 if ( PrtLvl >
PRINT_NONE ) ITS_RESTORE(iter_best);
1161 relres = absres_best / normr0;
1166 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,relres);
1177 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
1217 const SHORT StopType,
1221 const INT MIN_ITER = 0;
1229 const REAL cr_max = 0.99;
1230 const REAL cr_min = 0.174;
1234 INT restart1 = restart + 1;
1237 REAL r_norm, r_normb, gamma, t;
1242 REAL r_norm_old = 0.0;
1244 INT restart_max = restart;
1245 INT restart_min = 3;
1246 INT Restart = restart;
1252 REAL *c = NULL, *s = NULL, *rs = NULL;
1253 REAL *norms = NULL, *r = NULL, *w = NULL;
1254 REAL *work = NULL, *x_best = NULL;
1255 REAL **p = NULL, **hh = NULL;
1258 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling Safe VGMRes solver (STR) ...\n");
1261 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
1262 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
1269 while ( (work == NULL) && (restart > 5 ) ) {
1270 restart = restart - 5 ;
1272 printf(
"### WARNING: vGMRES restart number set to %d!\n", restart);
1273 restart1 = restart + 1;
1276 if ( work == NULL ) {
1277 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__);
1285 r = work; w = r + n; rs = w + n; c = rs + restart1;
1286 x_best = c + restart; s = x_best + n;
1288 for ( i = 0; i < restart1; i++ ) p[i] = s + restart + i*n;
1290 for ( i = 0; i < restart1; i++ ) hh[i] = p[restart] + n + i*restart;
1302 relres = r_norm/normr0;
1311 relres = r_normb/normr0;
1316 relres = normr0/normu;
1319 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
1324 if ( relres < tol )
goto FINISHED;
1333 while ( iter < MaxIt ) {
1335 rs[0] = r_norm_old = r_norm;
1344 if ( cr > cr_max || iter == 0 ) {
1345 Restart = restart_max;
1347 else if ( cr < cr_min ) {
1351 if ( Restart - d > restart_min ) {
1355 Restart = restart_max;
1361 while ( i < Restart && iter < MaxIt ) {
1374 for (j = 0; j < i; j ++) {
1385 for (j = 1; j < i; ++j) {
1387 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
1388 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
1390 t= hh[i][i-1]*hh[i][i-1];
1391 t+= hh[i-1][i-1]*hh[i-1][i-1];
1394 if (gamma == 0.0) gamma = epsmac;
1395 c[i-1] = hh[i-1][i-1] / gamma;
1396 s[i-1] = hh[i][i-1] / gamma;
1397 rs[i] = -s[i-1]*rs[i-1];
1398 rs[i-1] = c[i-1]*rs[i-1];
1399 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
1401 absres = r_norm = fabs(rs[i]);
1403 relres = absres/normr0;
1405 norms[iter] = relres;
1408 fasp_itinfo(PrtLvl, StopType, iter, relres, absres,
1409 norms[iter]/norms[iter-1]);
1412 if ( relres <= tol && iter >= MIN_ITER )
break;
1417 rs[i-1] = rs[i-1] / hh[i-1][i-1];
1418 for (k = i-2; k >= 0; k --) {
1420 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
1423 rs[k] = t / hh[k][k];
1444 goto RESTORE_BESTSOL;
1447 if ( absres < absres_best - maxdiff) {
1448 absres_best = absres;
1454 if ( relres <= tol && iter >= MIN_ITER ) {
1461 switch ( StopType ) {
1464 relres = absres/normr0;
1472 relres = absres/normr0;
1477 relres = absres/normu;
1481 norms[iter] = relres;
1483 if ( relres <= tol ) {
1494 for ( j = i; j > 0; j-- ) {
1495 rs[j-1] = -s[j-1]*rs[j];
1496 rs[j] = c[j-1]*rs[j];
1511 cr = r_norm / r_norm_old;
1516 if ( iter != iter_best ) {
1522 switch ( StopType ) {
1539 if ( absres > absres_best + maxdiff || isnan(absres) ) {
1540 if ( PrtLvl >
PRINT_NONE ) ITS_RESTORE(iter_best);
1542 relres = absres_best / normr0;
1547 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,relres);
1558 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
void fasp_darray_cp(const INT n, const REAL *x, REAL *y)
Copy an array to the other y=x.
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_itinfo(const INT ptrlvl, const INT stop_type, const INT iter, const REAL relres, const REAL absres, const REAL factor)
Print out iteration information for iterative solvers.
void fasp_chkerr(const SHORT status, const char *fctname)
Check error status and print out error messages before quit.
SHORT fasp_dvec_isnan(const dvector *u)
Check a dvector whether there is NAN.
REAL fasp_blas_darray_dotprod(const INT n, const REAL *x, const REAL *y)
Inner product of two arraies x and y.
REAL fasp_blas_darray_norm2(const INT n, const REAL *x)
L2 norm of array x.
void fasp_blas_darray_ax(const INT n, const REAL a, REAL *x)
x = a*x
void fasp_blas_darray_axpy(const INT n, const REAL a, const REAL *x, REAL *y)
y = a*x + y
void fasp_blas_dblc_mxv(const dBLCmat *A, const REAL *x, REAL *y)
Matrix-vector multiplication y = A*x.
void fasp_blas_dblc_aAxpy(const REAL alpha, const dBLCmat *A, const REAL *x, REAL *y)
Matrix-vector multiplication y = alpha*A*x + y.
void fasp_blas_dbsr_aAxpy(const REAL alpha, const dBSRmat *A, const REAL *x, REAL *y)
Compute y := alpha*A*x + y.
void fasp_blas_dbsr_mxv(const dBSRmat *A, const REAL *x, REAL *y)
Compute y := A*x.
void fasp_blas_dcsr_mxv(const dCSRmat *A, const REAL *x, REAL *y)
Matrix-vector multiplication y = A*x.
void fasp_blas_dcsr_aAxpy(const REAL alpha, const dCSRmat *A, const REAL *x, REAL *y)
Matrix-vector multiplication y = alpha*A*x + y.
void fasp_blas_dstr_aAxpy(const REAL alpha, const dSTRmat *A, const REAL *x, REAL *y)
Matrix-vector multiplication y = alpha*A*x + y.
void fasp_blas_dstr_mxv(const dSTRmat *A, const REAL *x, REAL *y)
Matrix-vector multiplication y = A*x.
INT fasp_solver_dcsr_spvgmres(const dCSRmat *A, const dvector *b, dvector *x, precond *pc, const REAL tol, const INT MaxIt, SHORT restart, const SHORT StopType, const SHORT PrtLvl)
Solve "Ax=b" using PGMRES(right preconditioned) iterative method in which the restart parameter can b...
INT fasp_solver_dblc_spvgmres(const dBLCmat *A, const dvector *b, dvector *x, precond *pc, const REAL tol, const INT MaxIt, SHORT restart, const SHORT StopType, const SHORT PrtLvl)
Preconditioned GMRES method for solving Au=b.
INT fasp_solver_dbsr_spvgmres(const dBSRmat *A, const dvector *b, dvector *x, precond *pc, const REAL tol, const INT MaxIt, SHORT restart, const SHORT StopType, const SHORT PrtLvl)
Solve "Ax=b" using PGMRES(right preconditioned) iterative method in which the restart parameter can b...
INT fasp_solver_dstr_spvgmres(const dSTRmat *A, const dvector *b, dvector *x, precond *pc, const REAL tol, const INT MaxIt, SHORT restart, const SHORT StopType, const SHORT PrtLvl)
Solve "Ax=b" using PGMRES(right preconditioned) iterative method in which the restart parameter can b...
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 ERROR_SOLVER_MAXIT
#define STOP_REL_RES
Definition of iterative solver stopping criteria types.
#define BIGREAL
Some global constants.
#define PRINT_NONE
Print level for all subroutines – not including DEBUG output.
Block REAL CSR matrix format.
Block sparse row storage matrix of REAL type.
Sparse matrix of REAL type in CSR format.
Structure matrix of REAL type.
Vector with n entries of REAL type.
REAL * val
actual vector entries
Preconditioner data and action.
void * data
data for preconditioner, void pointer
void(* fct)(REAL *, REAL *, void *)
action for preconditioner, void function pointer