28#include "fasp_functs.h"
78 const INT min_iter = 0;
84 const REAL cr_max = 0.99;
85 const REAL cr_min = 0.174;
92 REAL r_norm, b_norm, den_norm;
93 REAL epsilon, gamma, t;
94 REAL relres, normu, r_normb;
96 REAL *c = NULL, *s = NULL, *rs = NULL, *norms = NULL, *r = NULL;
97 REAL **p = NULL, **hh = NULL, **z=NULL;
100 REAL r_norm_old = 0.0;
102 INT restart_max = restart;
105 INT Restart = restart;
106 INT Restart1 = Restart + 1;
107 LONG worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
110 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling VFGMRes solver (CSR) ...\n");
113 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
114 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
121 while ( (work == NULL) && (Restart > 5) ) {
122 Restart = Restart - 5;
123 worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
125 Restart1 = Restart + 1;
128 if ( work == NULL ) {
129 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__ );
133 if ( PrtLvl >
PRINT_MIN && Restart < restart ) {
134 printf(
"### WARNING: vFGMRES restart number set to %d!\n", Restart);
142 r = work; rs = r + n; c = rs + Restart1; s = c + Restart;
143 for ( i = 0; i < Restart1; i++ ) p[i] = s + Restart + i*n;
144 for ( i = 0; i < Restart1; i++ ) hh[i] = p[Restart] + n + i*Restart;
145 for ( i = 0; i < Restart1; i++ ) z[i] = hh[Restart] + Restart + i*n;
156 ITS_PUTNORM(
"right-hand side", b_norm);
157 ITS_PUTNORM(
"residual", r_norm);
160 if ( b_norm > 0.0 ) den_norm = b_norm;
161 else den_norm = r_norm;
163 epsilon = tol*den_norm;
166 if ( r_norm < epsilon || r_norm < 1e-12*tol )
goto FINISHED;
168 if ( b_norm > 0.0 ) {
169 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm, norms[iter], 0);
172 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter], 0);
176 while ( iter < MaxIt ) {
180 if ( r_norm == 0.0 ) {
193 if ( cr > cr_max || iter == 0 ) {
194 Restart = restart_max;
196 else if ( cr < cr_min ) {
200 if ( Restart - d > restart_min ) Restart -= d;
201 else Restart = restart_max;
210 while ( i < Restart && iter < MaxIt ) {
218 pc->
fct(p[i-1], z[i-1], pc->
data);
223 for ( j = 0; j < i; j++ ) {
234 for ( j = 1; j < i; ++j ) {
236 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
237 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
239 t = hh[i][i-1] * hh[i][i-1];
240 t += hh[i-1][i-1] * hh[i-1][i-1];
242 if (gamma == 0.0) gamma = epsmac;
243 c[i-1] = hh[i-1][i-1] / gamma;
244 s[i-1] = hh[i][i-1] / gamma;
245 rs[i] = -s[i-1] * rs[i-1];
246 rs[i-1] = c[i-1] * rs[i-1];
247 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
249 r_norm = fabs(rs[i]);
250 norms[iter] = r_norm;
253 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm,
254 norms[iter], norms[iter]/norms[iter-1]);
257 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter],
258 norms[iter]/norms[iter-1]);
262 if (r_norm <= epsilon && iter >= min_iter)
break;
268 rs[i-1] = rs[i-1] / hh[i-1][i-1];
269 for ( k = i-2; k >= 0; k-- ) {
271 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
274 rs[k] = t / hh[k][k];
284 if ( r_norm <= epsilon && iter >= min_iter ) {
291 relres = r_norm/den_norm;
295 else pc->
fct(r, p[0], pc->
data);
297 relres = r_normb/den_norm;
301 relres = r_norm/normu;
304 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
308 if ( relres <= tol ) {
319 for ( j = i; j > 0; j-- ) {
320 rs[j-1] = -s[j-1]*rs[j];
321 rs[j] = c[j-1]*rs[j];
336 cr = r_norm / r_norm_old;
340 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,r_norm/den_norm);
353 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
396 const SHORT StopType,
400 const INT min_iter = 0;
406 const REAL cr_max = 0.99;
407 const REAL cr_min = 0.174;
414 REAL r_norm, b_norm, den_norm;
415 REAL epsilon, gamma, t;
416 REAL relres, normu, r_normb;
418 REAL *c = NULL, *s = NULL, *rs = NULL, *norms = NULL, *r = NULL;
419 REAL **p = NULL, **hh = NULL, **z=NULL;
422 REAL r_norm_old = 0.0;
424 INT restart_max = restart;
427 INT Restart = restart;
428 INT Restart1 = Restart + 1;
429 LONG worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
432 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling VFGMRes solver (BSR) ...\n");
435 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
436 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
443 while ( (work == NULL) && (Restart > 5) ) {
444 Restart = Restart - 5;
445 worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
447 Restart1 = Restart + 1;
450 if ( work == NULL ) {
451 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__ );
455 if ( PrtLvl >
PRINT_MIN && Restart < restart ) {
456 printf(
"### WARNING: vFGMRES restart number set to %d!\n", Restart);
464 r = work; rs = r + n; c = rs + Restart1; s = c + Restart;
465 for ( i = 0; i < Restart1; i++ ) p[i] = s + Restart + i*n;
466 for ( i = 0; i < Restart1; i++ ) hh[i] = p[Restart] + n + i*Restart;
467 for ( i = 0; i < Restart1; i++ ) z[i] = hh[Restart] + Restart + i*n;
478 ITS_PUTNORM(
"right-hand side", b_norm);
479 ITS_PUTNORM(
"residual", r_norm);
482 if ( b_norm > 0.0 ) den_norm = b_norm;
483 else den_norm = r_norm;
485 epsilon = tol*den_norm;
488 if ( r_norm < epsilon || r_norm < 1e-12*tol )
goto FINISHED;
490 if ( b_norm > 0.0 ) {
491 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm, norms[iter], 0);
494 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter], 0);
498 while ( iter < MaxIt ) {
502 if ( r_norm == 0.0 ) {
515 if ( cr > cr_max || iter == 0 ) {
516 Restart = restart_max;
518 else if ( cr < cr_min ) {
522 if ( Restart - d > restart_min ) Restart -= d;
523 else Restart = restart_max;
532 while ( i < Restart && iter < MaxIt ) {
540 pc->
fct(p[i-1], z[i-1], pc->
data);
545 for ( j = 0; j < i; j++ ) {
556 for ( j = 1; j < i; ++j ) {
558 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
559 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
561 t = hh[i][i-1] * hh[i][i-1];
562 t += hh[i-1][i-1] * hh[i-1][i-1];
564 if (gamma == 0.0) gamma = epsmac;
565 c[i-1] = hh[i-1][i-1] / gamma;
566 s[i-1] = hh[i][i-1] / gamma;
567 rs[i] = -s[i-1] * rs[i-1];
568 rs[i-1] = c[i-1] * rs[i-1];
569 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
571 r_norm = fabs(rs[i]);
572 norms[iter] = r_norm;
575 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm,
576 norms[iter], norms[iter]/norms[iter-1]);
579 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter],
580 norms[iter]/norms[iter-1]);
584 if (r_norm <= epsilon && iter >= min_iter)
break;
590 rs[i-1] = rs[i-1] / hh[i-1][i-1];
591 for ( k = i-2; k >= 0; k-- ) {
593 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
596 rs[k] = t / hh[k][k];
606 if ( r_norm <= epsilon && iter >= min_iter ) {
613 relres = r_norm/den_norm;
617 else pc->
fct(r, p[0], pc->
data);
619 relres = r_normb/den_norm;
623 relres = r_norm/normu;
626 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
630 if ( relres <= tol ) {
641 for ( j = i; j > 0; j-- ) {
642 rs[j-1] = -s[j-1]*rs[j];
643 rs[j] = c[j-1]*rs[j];
658 cr = r_norm / r_norm_old;
662 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,r_norm/den_norm);
675 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
721 const SHORT StopType,
725 const INT min_iter = 0;
731 const REAL cr_max = 0.99;
732 const REAL cr_min = 0.174;
739 REAL r_norm, b_norm, den_norm;
740 REAL epsilon, gamma, t;
741 REAL relres, normu, r_normb;
743 REAL *c = NULL, *s = NULL, *rs = NULL, *norms = NULL, *r = NULL;
744 REAL **p = NULL, **hh = NULL, **z=NULL;
747 REAL r_norm_old = 0.0;
749 INT restart_max = restart;
752 INT Restart = restart;
753 INT Restart1 = Restart + 1;
754 LONG worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
757 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling VFGMRes solver (BLC) ...\n");
760 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
761 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
768 while ( (work == NULL) && (Restart > 5) ) {
769 Restart = Restart - 5;
770 worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
772 Restart1 = Restart + 1;
775 if ( work == NULL ) {
776 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__ );
780 if ( PrtLvl >
PRINT_MIN && Restart < restart ) {
781 printf(
"### WARNING: vFGMRES restart number set to %d!\n", Restart);
789 r = work; rs = r + n; c = rs + Restart1; s = c + Restart;
790 for ( i = 0; i < Restart1; i++ ) p[i] = s + Restart + i*n;
791 for ( i = 0; i < Restart1; i++ ) hh[i] = p[Restart] + n + i*Restart;
792 for ( i = 0; i < Restart1; i++ ) z[i] = hh[Restart] + Restart + i*n;
803 ITS_PUTNORM(
"right-hand side", b_norm);
804 ITS_PUTNORM(
"residual", r_norm);
807 if ( b_norm > 0.0 ) den_norm = b_norm;
808 else den_norm = r_norm;
810 epsilon = tol*den_norm;
813 if ( r_norm < epsilon || r_norm < 1e-12 * tol )
goto FINISHED;
815 if ( b_norm > 0.0 ) {
816 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm, norms[iter], 0);
819 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter], 0);
823 while ( iter < MaxIt ) {
827 if ( r_norm == 0.0 ) {
840 if ( cr > cr_max || iter == 0 ) {
841 Restart = restart_max;
843 else if ( cr < cr_min ) {
847 if ( Restart - d > restart_min ) Restart -= d;
848 else Restart = restart_max;
857 while ( i < Restart && iter < MaxIt ) {
865 pc->
fct(p[i-1], z[i-1], pc->
data);
870 for ( j = 0; j < i; j++ ) {
881 for ( j = 1; j < i; ++j ) {
883 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
884 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
886 t = hh[i][i-1] * hh[i][i-1];
887 t += hh[i-1][i-1] * hh[i-1][i-1];
889 if (gamma == 0.0) gamma = epsmac;
890 c[i-1] = hh[i-1][i-1] / gamma;
891 s[i-1] = hh[i][i-1] / gamma;
892 rs[i] = -s[i-1] * rs[i-1];
893 rs[i-1] = c[i-1] * rs[i-1];
894 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
896 r_norm = fabs(rs[i]);
897 norms[iter] = r_norm;
900 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm,
901 norms[iter], norms[iter]/norms[iter-1]);
904 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter],
905 norms[iter]/norms[iter-1]);
909 if (r_norm <= epsilon && iter >= min_iter)
break;
915 rs[i-1] = rs[i-1] / hh[i-1][i-1];
916 for ( k = i-2; k >= 0; k-- ) {
918 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
921 rs[k] = t / hh[k][k];
931 if ( r_norm <= epsilon && iter >= min_iter ) {
938 relres = r_norm/den_norm;
942 else pc->
fct(r, p[0], pc->
data);
944 relres = r_normb/den_norm;
948 relres = r_norm/normu;
951 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
955 if ( relres <= tol ) {
966 for ( j = i; j > 0; j-- ) {
967 rs[j-1] = -s[j-1]*rs[j];
968 rs[j] = c[j-1]*rs[j];
983 cr = r_norm / r_norm_old;
987 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,r_norm/den_norm);
1000 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
1003 if ( iter >= MaxIt )
1042 const SHORT restart,
1043 const SHORT StopType,
1047 const INT min_iter = 0;
1053 const REAL cr_max = 0.99;
1054 const REAL cr_min = 0.174;
1061 REAL r_norm, b_norm, den_norm;
1062 REAL epsilon, gamma, t;
1064 REAL *c = NULL, *s = NULL, *rs = NULL;
1065 REAL *norms = NULL, *r = NULL;
1066 REAL **p = NULL, **hh = NULL, **z=NULL;
1070 REAL r_norm_old = 0.0;
1072 INT restart_max = restart;
1073 INT restart_min = 3;
1075 INT Restart = restart;
1076 INT Restart1 = Restart + 1;
1077 LONG worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
1080 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling VFGMRes solver (MatFree) ...\n");
1083 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
1084 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
1091 while ( (work == NULL) && (Restart > 5) ) {
1092 Restart = Restart - 5;
1093 worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
1095 Restart1 = Restart + 1;
1098 if ( work == NULL ) {
1099 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__ );
1103 if ( PrtLvl >
PRINT_MIN && Restart < restart ) {
1104 printf(
"### WARNING: vFGMRES restart number set to %d!\n", Restart);
1112 r = work; rs = r + n; c = rs + Restart1; s = c + Restart;
1113 for (i = 0; i < Restart1; i ++) p[i] = s + Restart + i*n;
1114 for (i = 0; i < Restart1; i ++) hh[i] = p[Restart] + n + i*Restart;
1115 for (i = 0; i < Restart1; i ++) z[i] = hh[Restart] + Restart + i*n;
1126 ITS_PUTNORM(
"right-hand side", b_norm);
1127 ITS_PUTNORM(
"residual", r_norm);
1130 if (b_norm > 0.0) den_norm = b_norm;
1131 else den_norm = r_norm;
1133 epsilon = tol*den_norm;
1136 while (iter < MaxIt) {
1138 r_norm_old = r_norm;
1139 if (r_norm == 0.0) {
1152 if (cr > cr_max || iter == 0) {
1153 Restart = restart_max;
1155 else if (cr < cr_min) {
1159 if ( Restart - d > restart_min ) Restart -= d;
1160 else Restart = restart_max;
1163 if (r_norm <= epsilon && iter >= min_iter) {
1168 if (r_norm <= epsilon) {
1181 while (i < Restart && iter < MaxIt) {
1187 else pc->
fct(p[i-1], z[i-1], pc->
data);
1189 mf->
fct(mf->
data, z[i-1], p[i]);
1192 for (j = 0; j < i; j ++) {
1203 for (j = 1; j < i; ++j) {
1205 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
1206 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
1208 t= hh[i][i-1]*hh[i][i-1];
1209 t+= hh[i-1][i-1]*hh[i-1][i-1];
1211 if (gamma == 0.0) gamma = epsmac;
1212 c[i-1] = hh[i-1][i-1] / gamma;
1213 s[i-1] = hh[i][i-1] / gamma;
1214 rs[i] = -s[i-1]*rs[i-1];
1215 rs[i-1] = c[i-1]*rs[i-1];
1216 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
1218 r_norm = fabs(rs[i]);
1219 norms[iter] = r_norm;
1222 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm,
1223 norms[iter], norms[iter]/norms[iter-1]);
1226 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter],
1227 norms[iter]/norms[iter-1]);
1231 if (r_norm <= epsilon && iter >= min_iter)
break;
1237 rs[i-1] = rs[i-1] / hh[i-1][i-1];
1238 for (k = i-2; k >= 0; k --) {
1240 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
1243 rs[k] = t / hh[k][k];
1252 if (r_norm <= epsilon && iter >= min_iter) {
1257 if (r_norm <= epsilon) {
1268 for (j = i; j > 0; j--) {
1269 rs[j-1] = -s[j-1]*rs[j];
1270 rs[j] = c[j-1]*rs[j];
1285 cr = r_norm / r_norm_old;
1289 if (PrtLvl >
PRINT_NONE) ITS_FINAL(iter,MaxIt,r_norm);
1301 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.
REAL fasp_blas_darray_dotprod(const INT n, const REAL *x, const REAL *y)
Inner product of two arraies x and y.
void fasp_blas_darray_axpby(const INT n, const REAL a, const REAL *x, const REAL b, REAL *y)
y = a*x + b*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.
INT fasp_solver_dblc_pvfgmres(dBLCmat *A, dvector *b, dvector *x, precond *pc, const REAL tol, const INT MaxIt, const SHORT restart, const SHORT StopType, const SHORT PrtLvl)
Solve "Ax=b" using PFGMRES (right preconditioned) iterative method in which the restart parameter can...
INT fasp_solver_dcsr_pvfgmres(dCSRmat *A, dvector *b, dvector *x, precond *pc, const REAL tol, const INT MaxIt, const SHORT restart, const SHORT StopType, const SHORT PrtLvl)
Solve "Ax=b" using PFGMRES(right preconditioned) iterative method in which the restart parameter can ...
INT fasp_solver_dbsr_pvfgmres(dBSRmat *A, dvector *b, dvector *x, precond *pc, const REAL tol, const INT MaxIt, const SHORT restart, const SHORT StopType, const SHORT PrtLvl)
Solve "Ax=b" using PFGMRES(right preconditioned) iterative method in which the restart parameter can ...
INT fasp_solver_pvfgmres(mxv_matfree *mf, dvector *b, dvector *x, precond *pc, const REAL tol, const INT MaxIt, const SHORT restart, const SHORT StopType, const SHORT PrtLvl)
Solve "Ax=b" using PFGMRES(right preconditioned) iterative method in which the restart parameter can ...
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 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.
Vector with n entries of REAL type.
REAL * val
actual vector entries
Matrix-vector multiplication, replace the actual matrix.
void * data
data for MxV, can be a Matrix or something else
void(* fct)(const void *, const REAL *, REAL *)
action for MxV, void function pointer
Preconditioner data and action.
void * data
data for preconditioner, void pointer
void(* fct)(REAL *, REAL *, void *)
action for preconditioner, void function pointer