29#include "fasp_functs.h"
77 const INT MIN_ITER = 0;
83 INT restart1 = restart + 1;
86 REAL r_norm, r_normb, gamma, t;
94 REAL *c = NULL, *s = NULL, *rs = NULL;
95 REAL *norms = NULL, *r = NULL, *w = NULL;
96 REAL *work = NULL, *x_best = NULL;
97 REAL **p = NULL, **hh = NULL;
100 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling Safe GMRes solver (CSR) ...\n");
103 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
104 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
111 while ( (work == NULL) && (restart > 5 ) ) {
112 restart = restart - 5 ;
114 printf(
"### WARNING: GMRES restart number set to %d!\n", restart);
115 restart1 = restart + 1;
118 if ( work == NULL ) {
119 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__);
127 r = work; w = r + n; rs = w + n; c = rs + restart1;
128 x_best = c + restart; s = x_best + n;
130 for ( i = 0; i < restart1; i++ ) p[i] = s + restart + i*n;
132 for ( i = 0; i < restart1; i++ ) hh[i] = p[restart] + n + i*restart;
144 relres = r_norm/normr0;
153 relres = r_normb/normr0;
158 relres = normr0/normu;
161 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
166 if ( relres < tol )
goto FINISHED;
175 while ( iter < MaxIt ) {
185 while ( i < restart && iter < MaxIt ) {
198 for ( j = 0; j < i; j++ ) {
209 for (j = 1; j < i; ++j) {
211 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
212 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
214 t= hh[i][i-1]*hh[i][i-1];
215 t+= hh[i-1][i-1]*hh[i-1][i-1];
218 if (gamma == 0.0) gamma = epsmac;
219 c[i-1] = hh[i-1][i-1] / gamma;
220 s[i-1] = hh[i][i-1] / gamma;
221 rs[i] = -s[i-1]*rs[i-1];
222 rs[i-1] = c[i-1]*rs[i-1];
223 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
225 absres = r_norm = fabs(rs[i]);
227 relres = absres/normr0;
229 norms[iter] = relres;
232 fasp_itinfo(PrtLvl, StopType, iter, relres, absres,
233 norms[iter]/norms[iter-1]);
236 if ( relres <= tol && iter >= MIN_ITER )
break;
241 rs[i-1] = rs[i-1] / hh[i-1][i-1];
242 for ( k = i-2; k >= 0; k-- ) {
244 for (j = k+1; j < i; j++) t -= hh[k][j]*rs[j];
247 rs[k] = t / hh[k][k];
268 goto RESTORE_BESTSOL;
271 if ( absres < absres_best - maxdiff) {
272 absres_best = absres;
278 if ( relres <= tol && iter >= MIN_ITER ) {
285 switch ( StopType ) {
288 relres = absres/normr0;
296 relres = absres/normr0;
301 relres = absres/normu;
305 norms[iter] = relres;
307 if ( relres <= tol ) {
318 for (j = i; j > 0; j--) {
319 rs[j-1] = -s[j-1]*rs[j];
320 rs[j] = c[j-1]*rs[j];
335 if ( iter != iter_best ) {
341 switch ( StopType ) {
358 if ( absres > absres_best + maxdiff || isnan(absres) ) {
359 if ( PrtLvl >
PRINT_NONE ) ITS_RESTORE(iter_best);
361 relres = absres_best / normr0;
366 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,relres);
377 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
416 const SHORT StopType,
420 const INT MIN_ITER = 0;
426 INT restart1 = restart + 1;
429 REAL r_norm, r_normb, gamma, t;
437 REAL *c = NULL, *s = NULL, *rs = NULL;
438 REAL *norms = NULL, *r = NULL, *w = NULL;
439 REAL *work = NULL, *x_best = NULL;
440 REAL **p = NULL, **hh = NULL;
443 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling Safe GMRes solver (BSR) ...\n");
446 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
447 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
454 while ( (work == NULL) && (restart > 5 ) ) {
455 restart = restart - 5 ;
457 printf(
"### WARNING: GMRES restart number set to %d!\n", restart);
458 restart1 = restart + 1;
461 if ( work == NULL ) {
462 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__);
470 r = work; w = r + n; rs = w + n; c = rs + restart1;
471 x_best = c + restart; s = x_best + n;
473 for ( i = 0; i < restart1; i++ ) p[i] = s + restart + i*n;
475 for ( i = 0; i < restart1; i++ ) hh[i] = p[restart] + n + i*restart;
487 relres = r_norm/normr0;
496 relres = r_normb/normr0;
501 relres = normr0/normu;
504 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
509 if ( relres < tol )
goto FINISHED;
518 while ( iter < MaxIt ) {
528 while ( i < restart && iter < MaxIt ) {
541 for ( j = 0; j < i; j++ ) {
552 for (j = 1; j < i; ++j) {
554 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
555 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
557 t= hh[i][i-1]*hh[i][i-1];
558 t+= hh[i-1][i-1]*hh[i-1][i-1];
561 if (gamma == 0.0) gamma = epsmac;
562 c[i-1] = hh[i-1][i-1] / gamma;
563 s[i-1] = hh[i][i-1] / gamma;
564 rs[i] = -s[i-1]*rs[i-1];
565 rs[i-1] = c[i-1]*rs[i-1];
566 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
568 absres = r_norm = fabs(rs[i]);
570 relres = absres/normr0;
572 norms[iter] = relres;
575 fasp_itinfo(PrtLvl, StopType, iter, relres, absres,
576 norms[iter]/norms[iter-1]);
579 if ( relres <= tol && iter >= MIN_ITER )
break;
584 rs[i-1] = rs[i-1] / hh[i-1][i-1];
585 for ( k = i-2; k >= 0; k-- ) {
587 for (j = k+1; j < i; j++) t -= hh[k][j]*rs[j];
590 rs[k] = t / hh[k][k];
611 goto RESTORE_BESTSOL;
614 if ( absres < absres_best - maxdiff) {
615 absres_best = absres;
621 if ( relres <= tol && iter >= MIN_ITER ) {
628 switch ( StopType ) {
631 relres = absres/normr0;
639 relres = absres/normr0;
644 relres = absres/normu;
648 norms[iter] = relres;
650 if ( relres <= tol ) {
661 for (j = i; j > 0; j--) {
662 rs[j-1] = -s[j-1]*rs[j];
663 rs[j] = c[j-1]*rs[j];
678 if ( iter != iter_best ) {
684 switch ( StopType ) {
701 if ( absres > absres_best + maxdiff || isnan(absres) ) {
702 if ( PrtLvl >
PRINT_NONE ) ITS_RESTORE(iter_best);
704 relres = absres_best / normr0;
709 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,relres);
720 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
759 const SHORT StopType,
763 const INT MIN_ITER = 0;
769 INT restart1 = restart + 1;
772 REAL r_norm, r_normb, gamma, t;
780 REAL *c = NULL, *s = NULL, *rs = NULL;
781 REAL *norms = NULL, *r = NULL, *w = NULL;
782 REAL *work = NULL, *x_best = NULL;
783 REAL **p = NULL, **hh = NULL;
786 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling Safe GMRes solver (BLC) ...\n");
789 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
790 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
797 while ( (work == NULL) && (restart > 5 ) ) {
798 restart = restart - 5 ;
800 printf(
"### WARNING: GMRES restart number set to %d!\n", restart);
801 restart1 = restart + 1;
804 if ( work == NULL ) {
805 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__);
813 r = work; w = r + n; rs = w + n; c = rs + restart1;
814 x_best = c + restart; s = x_best + n;
816 for ( i = 0; i < restart1; i++ ) p[i] = s + restart + i*n;
818 for ( i = 0; i < restart1; i++ ) hh[i] = p[restart] + n + i*restart;
830 relres = r_norm/normr0;
839 relres = r_normb/normr0;
844 relres = normr0/normu;
847 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
852 if ( relres < tol )
goto FINISHED;
861 while ( iter < MaxIt ) {
871 while ( i < restart && iter < MaxIt ) {
884 for ( j = 0; j < i; j++ ) {
895 for (j = 1; j < i; ++j) {
897 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
898 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
900 t= hh[i][i-1]*hh[i][i-1];
901 t+= hh[i-1][i-1]*hh[i-1][i-1];
904 if (gamma == 0.0) gamma = epsmac;
905 c[i-1] = hh[i-1][i-1] / gamma;
906 s[i-1] = hh[i][i-1] / gamma;
907 rs[i] = -s[i-1]*rs[i-1];
908 rs[i-1] = c[i-1]*rs[i-1];
909 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
911 absres = r_norm = fabs(rs[i]);
913 relres = absres/normr0;
915 norms[iter] = relres;
918 fasp_itinfo(PrtLvl, StopType, iter, relres, absres,
919 norms[iter]/norms[iter-1]);
922 if ( relres <= tol && iter >= MIN_ITER )
break;
927 rs[i-1] = rs[i-1] / hh[i-1][i-1];
928 for ( k = i-2; k >= 0; k-- ) {
930 for (j = k+1; j < i; j++) t -= hh[k][j]*rs[j];
933 rs[k] = t / hh[k][k];
954 goto RESTORE_BESTSOL;
957 if ( absres < absres_best - maxdiff) {
958 absres_best = absres;
964 if ( relres <= tol && iter >= MIN_ITER ) {
971 switch ( StopType ) {
974 relres = absres/normr0;
982 relres = absres/normr0;
987 relres = absres/normu;
991 norms[iter] = relres;
993 if ( relres <= tol ) {
1004 for (j = i; j > 0; j--) {
1005 rs[j-1] = -s[j-1]*rs[j];
1006 rs[j] = c[j-1]*rs[j];
1021 if ( iter != iter_best ) {
1027 switch ( StopType ) {
1044 if ( absres > absres_best + maxdiff || isnan(absres) ) {
1045 if ( PrtLvl >
PRINT_NONE ) ITS_RESTORE(iter_best);
1047 relres = absres_best / normr0;
1052 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,relres);
1063 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
1066 if ( iter >= MaxIt )
1102 const SHORT StopType,
1106 const INT MIN_ITER = 0;
1112 INT restart1 = restart + 1;
1115 REAL r_norm, r_normb, gamma, t;
1123 REAL *c = NULL, *s = NULL, *rs = NULL;
1124 REAL *norms = NULL, *r = NULL, *w = NULL;
1125 REAL *work = NULL, *x_best = NULL;
1126 REAL **p = NULL, **hh = NULL;
1129 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling Safe GMRes solver (STR) ...\n");
1132 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
1133 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
1140 while ( (work == NULL) && (restart > 5 ) ) {
1141 restart = restart - 5 ;
1143 printf(
"### WARNING: GMRES restart number set to %d!\n", restart);
1144 restart1 = restart + 1;
1147 if ( work == NULL ) {
1148 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__);
1156 r = work; w = r + n; rs = w + n; c = rs + restart1;
1157 x_best = c + restart; s = x_best + n;
1159 for ( i = 0; i < restart1; i++ ) p[i] = s + restart + i*n;
1161 for ( i = 0; i < restart1; i++ ) hh[i] = p[restart] + n + i*restart;
1173 relres = r_norm/normr0;
1182 relres = r_normb/normr0;
1187 relres = normr0/normu;
1190 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
1195 if ( relres < tol )
goto FINISHED;
1204 while ( iter < MaxIt ) {
1214 while ( i < restart && iter < MaxIt ) {
1227 for ( j = 0; j < i; j++ ) {
1238 for (j = 1; j < i; ++j) {
1240 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
1241 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
1243 t= hh[i][i-1]*hh[i][i-1];
1244 t+= hh[i-1][i-1]*hh[i-1][i-1];
1247 if (gamma == 0.0) gamma = epsmac;
1248 c[i-1] = hh[i-1][i-1] / gamma;
1249 s[i-1] = hh[i][i-1] / gamma;
1250 rs[i] = -s[i-1]*rs[i-1];
1251 rs[i-1] = c[i-1]*rs[i-1];
1252 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
1254 absres = r_norm = fabs(rs[i]);
1256 relres = absres/normr0;
1258 norms[iter] = relres;
1261 fasp_itinfo(PrtLvl, StopType, iter, relres, absres,
1262 norms[iter]/norms[iter-1]);
1265 if ( relres <= tol && iter >= MIN_ITER )
break;
1270 rs[i-1] = rs[i-1] / hh[i-1][i-1];
1271 for ( k = i-2; k >= 0; k-- ) {
1273 for (j = k+1; j < i; j++) t -= hh[k][j]*rs[j];
1276 rs[k] = t / hh[k][k];
1297 goto RESTORE_BESTSOL;
1300 if ( absres < absres_best - maxdiff) {
1301 absres_best = absres;
1307 if ( relres <= tol && iter >= MIN_ITER ) {
1314 switch ( StopType ) {
1317 relres = absres/normr0;
1325 relres = absres/normr0;
1330 relres = absres/normu;
1334 norms[iter] = relres;
1336 if ( relres <= tol ) {
1347 for (j = i; j > 0; j--) {
1348 rs[j-1] = -s[j-1]*rs[j];
1349 rs[j] = c[j-1]*rs[j];
1364 if ( iter != iter_best ) {
1370 switch ( StopType ) {
1387 if ( absres > absres_best + maxdiff || isnan(absres) ) {
1388 if ( PrtLvl >
PRINT_NONE ) ITS_RESTORE(iter_best);
1390 relres = absres_best / normr0;
1395 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,relres);
1406 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
1409 if ( iter >= MaxIt )
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_dbsr_spgmres(const dBSRmat *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 with safe-guard.
INT fasp_solver_dcsr_spgmres(const dCSRmat *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 with safe-guard.
INT fasp_solver_dstr_spgmres(const dSTRmat *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 with safe-guard.
INT fasp_solver_dblc_spgmres(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 with safe-guard.
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