26#include "fasp_functs.h"
73 const INT min_iter = 0;
79 const REAL cr_max = 0.99;
80 const REAL cr_min = 0.174;
87 REAL r_norm, b_norm, den_norm;
88 REAL epsilon, gamma, t;
89 REAL relres, normu, r_normb;
91 REAL *c = NULL, *s = NULL, *rs = NULL, *norms = NULL, *r = NULL;
92 REAL **p = NULL, **hh = NULL, **z=NULL;
95 REAL r_norm_old = 0.0;
97 INT restart_max = restart;
100 INT Restart = restart;
101 INT Restart1 = Restart + 1;
102 LONG worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
105 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling VFGMRes solver (CSR) ...\n");
108 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
109 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
116 while ( (work == NULL) && (Restart > 5) ) {
117 Restart = Restart - 5;
118 worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
120 Restart1 = Restart + 1;
123 if ( work == NULL ) {
124 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__ );
128 if ( PrtLvl >
PRINT_MIN && Restart < restart ) {
129 printf(
"### WARNING: vFGMRES restart number set to %d!\n", Restart);
137 r = work; rs = r + n; c = rs + Restart1; s = c + Restart;
138 for ( i = 0; i < Restart1; i++ ) p[i] = s + Restart + i*n;
139 for ( i = 0; i < Restart1; i++ ) hh[i] = p[Restart] + n + i*Restart;
140 for ( i = 0; i < Restart1; i++ ) z[i] = hh[Restart] + Restart + i*n;
151 ITS_PUTNORM(
"right-hand side", b_norm);
152 ITS_PUTNORM(
"residual", r_norm);
155 if ( b_norm > 0.0 ) den_norm = b_norm;
156 else den_norm = r_norm;
158 epsilon = tol*den_norm;
161 if ( r_norm < epsilon || r_norm < abstol )
goto FINISHED;
163 if ( b_norm > 0.0 ) {
164 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm, norms[iter], 0);
167 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter], 0);
171 while ( iter < MaxIt ) {
175 if ( r_norm == 0.0 ) {
188 if ( cr > cr_max || iter == 0 ) {
189 Restart = restart_max;
191 else if ( cr < cr_min ) {
195 if ( Restart - d > restart_min ) Restart -= d;
196 else Restart = restart_max;
205 while ( i < Restart && iter < MaxIt ) {
213 pc->
fct(p[i-1], z[i-1], pc->
data);
218 for ( j = 0; j < i; j++ ) {
229 for ( j = 1; j < i; ++j ) {
231 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
232 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
234 t = hh[i][i-1] * hh[i][i-1];
235 t += hh[i-1][i-1] * hh[i-1][i-1];
237 if (gamma == 0.0) gamma = epsmac;
238 c[i-1] = hh[i-1][i-1] / gamma;
239 s[i-1] = hh[i][i-1] / gamma;
240 rs[i] = -s[i-1] * rs[i-1];
241 rs[i-1] = c[i-1] * rs[i-1];
242 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
244 r_norm = fabs(rs[i]);
245 norms[iter] = r_norm;
248 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm,
249 norms[iter], norms[iter]/norms[iter-1]);
252 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter],
253 norms[iter]/norms[iter-1]);
257 if (r_norm <= epsilon && iter >= min_iter)
break;
263 rs[i-1] = rs[i-1] / hh[i-1][i-1];
264 for ( k = i-2; k >= 0; k-- ) {
266 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
269 rs[k] = t / hh[k][k];
279 if ( r_norm <= epsilon && iter >= min_iter ) {
286 relres = r_norm/den_norm;
290 else pc->
fct(r, p[0], pc->
data);
292 relres = r_normb/den_norm;
296 relres = r_norm/normu;
299 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
303 if ( relres <= tol ) {
314 for ( j = i; j > 0; j-- ) {
315 rs[j-1] = -s[j-1]*rs[j];
316 rs[j] = c[j-1]*rs[j];
331 cr = r_norm / r_norm_old;
335 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,r_norm/den_norm);
348 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
387 const REAL tol,
const REAL abstol,
const INT MaxIt,
392 const INT min_iter = 0;
398 const REAL cr_max = 0.99;
399 const REAL cr_min = 0.174;
406 REAL r_norm, b_norm, den_norm;
407 REAL epsilon, gamma, t;
408 REAL relres, normu, r_normb;
410 REAL *c = NULL, *s = NULL, *rs = NULL, *norms = NULL, *r = NULL;
411 REAL **p = NULL, **hh = NULL, **z=NULL;
414 REAL r_norm_old = 0.0;
416 INT restart_max = restart;
419 INT Restart = restart;
420 INT Restart1 = Restart + 1;
421 LONG worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
424 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling VFGMRes solver (BSR) ...\n");
427 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
428 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
435 while ( (work == NULL) && (Restart > 5) ) {
436 Restart = Restart - 5;
437 worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
439 Restart1 = Restart + 1;
442 if ( work == NULL ) {
443 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__ );
447 if ( PrtLvl >
PRINT_MIN && Restart < restart ) {
448 printf(
"### WARNING: vFGMRES restart number set to %d!\n", Restart);
456 r = work; rs = r + n; c = rs + Restart1; s = c + Restart;
457 for ( i = 0; i < Restart1; i++ ) p[i] = s + Restart + i*n;
458 for ( i = 0; i < Restart1; i++ ) hh[i] = p[Restart] + n + i*Restart;
459 for ( i = 0; i < Restart1; i++ ) z[i] = hh[Restart] + Restart + i*n;
470 ITS_PUTNORM(
"right-hand side", b_norm);
471 ITS_PUTNORM(
"residual", r_norm);
474 if ( b_norm > 0.0 ) den_norm = b_norm;
475 else den_norm = r_norm;
477 epsilon = tol*den_norm;
480 if (r_norm < epsilon || r_norm < abstol)
goto FINISHED;
482 if ( b_norm > 0.0 ) {
483 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm, norms[iter], 0);
486 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter], 0);
490 while ( iter < MaxIt ) {
494 if ( r_norm == 0.0 ) {
507 if ( cr > cr_max || iter == 0 ) {
508 Restart = restart_max;
510 else if ( cr < cr_min ) {
514 if ( Restart - d > restart_min ) Restart -= d;
515 else Restart = restart_max;
524 while ( i < Restart && iter < MaxIt ) {
532 pc->
fct(p[i-1], z[i-1], pc->
data);
537 for ( j = 0; j < i; j++ ) {
548 for ( j = 1; j < i; ++j ) {
550 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
551 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
553 t = hh[i][i-1] * hh[i][i-1];
554 t += hh[i-1][i-1] * hh[i-1][i-1];
556 if (gamma == 0.0) gamma = epsmac;
557 c[i-1] = hh[i-1][i-1] / gamma;
558 s[i-1] = hh[i][i-1] / gamma;
559 rs[i] = -s[i-1] * rs[i-1];
560 rs[i-1] = c[i-1] * rs[i-1];
561 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
563 r_norm = fabs(rs[i]);
564 norms[iter] = r_norm;
567 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm,
568 norms[iter], norms[iter]/norms[iter-1]);
571 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter],
572 norms[iter]/norms[iter-1]);
576 if (r_norm <= epsilon && iter >= min_iter)
break;
582 rs[i-1] = rs[i-1] / hh[i-1][i-1];
583 for ( k = i-2; k >= 0; k-- ) {
585 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
588 rs[k] = t / hh[k][k];
598 if ( r_norm <= epsilon && iter >= min_iter ) {
605 relres = r_norm/den_norm;
609 else pc->
fct(r, p[0], pc->
data);
611 relres = r_normb/den_norm;
615 relres = r_norm/normu;
618 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
622 if ( relres <= tol ) {
633 for ( j = i; j > 0; j-- ) {
634 rs[j-1] = -s[j-1]*rs[j];
635 rs[j] = c[j-1]*rs[j];
650 cr = r_norm / r_norm_old;
654 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,r_norm/den_norm);
667 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
708 const REAL tol,
const REAL abstol,
const INT MaxIt,
713 const INT min_iter = 0;
719 const REAL cr_max = 0.99;
720 const REAL cr_min = 0.174;
727 REAL r_norm, b_norm, den_norm;
728 REAL epsilon, gamma, t;
729 REAL relres, normu, r_normb;
731 REAL *c = NULL, *s = NULL, *rs = NULL, *norms = NULL, *r = NULL;
732 REAL **p = NULL, **hh = NULL, **z=NULL;
735 REAL r_norm_old = 0.0;
737 INT restart_max = restart;
740 INT Restart = restart;
741 INT Restart1 = Restart + 1;
742 LONG worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
745 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling VFGMRes solver (BLC) ...\n");
748 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
749 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
756 while ( (work == NULL) && (Restart > 5) ) {
757 Restart = Restart - 5;
758 worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
760 Restart1 = Restart + 1;
763 if ( work == NULL ) {
764 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__ );
768 if ( PrtLvl >
PRINT_MIN && Restart < restart ) {
769 printf(
"### WARNING: vFGMRES restart number set to %d!\n", Restart);
777 r = work; rs = r + n; c = rs + Restart1; s = c + Restart;
778 for ( i = 0; i < Restart1; i++ ) p[i] = s + Restart + i*n;
779 for ( i = 0; i < Restart1; i++ ) hh[i] = p[Restart] + n + i*Restart;
780 for ( i = 0; i < Restart1; i++ ) z[i] = hh[Restart] + Restart + i*n;
791 ITS_PUTNORM(
"right-hand side", b_norm);
792 ITS_PUTNORM(
"residual", r_norm);
795 if ( b_norm > 0.0 ) den_norm = b_norm;
796 else den_norm = r_norm;
798 epsilon = tol*den_norm;
801 if (r_norm < epsilon || r_norm < abstol)
goto FINISHED;
803 if ( b_norm > 0.0 ) {
804 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm, norms[iter], 0);
807 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter], 0);
811 while ( iter < MaxIt ) {
815 if ( r_norm == 0.0 ) {
828 if ( cr > cr_max || iter == 0 ) {
829 Restart = restart_max;
831 else if ( cr < cr_min ) {
835 if ( Restart - d > restart_min ) Restart -= d;
836 else Restart = restart_max;
845 while ( i < Restart && iter < MaxIt ) {
853 pc->
fct(p[i-1], z[i-1], pc->
data);
858 for ( j = 0; j < i; j++ ) {
869 for ( j = 1; j < i; ++j ) {
871 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
872 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
874 t = hh[i][i-1] * hh[i][i-1];
875 t += hh[i-1][i-1] * hh[i-1][i-1];
877 if (gamma == 0.0) gamma = epsmac;
878 c[i-1] = hh[i-1][i-1] / gamma;
879 s[i-1] = hh[i][i-1] / gamma;
880 rs[i] = -s[i-1] * rs[i-1];
881 rs[i-1] = c[i-1] * rs[i-1];
882 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
884 r_norm = fabs(rs[i]);
885 norms[iter] = r_norm;
888 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm,
889 norms[iter], norms[iter]/norms[iter-1]);
892 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter],
893 norms[iter]/norms[iter-1]);
897 if (r_norm <= epsilon && iter >= min_iter)
break;
903 rs[i-1] = rs[i-1] / hh[i-1][i-1];
904 for ( k = i-2; k >= 0; k-- ) {
906 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
909 rs[k] = t / hh[k][k];
919 if ( r_norm <= epsilon && iter >= min_iter ) {
926 relres = r_norm/den_norm;
930 else pc->
fct(r, p[0], pc->
data);
932 relres = r_normb/den_norm;
936 relres = r_norm/normu;
939 printf(
"### ERROR: Unknown stopping type! [%s]\n", __FUNCTION__);
943 if ( relres <= tol ) {
954 for ( j = i; j > 0; j-- ) {
955 rs[j-1] = -s[j-1]*rs[j];
956 rs[j] = c[j-1]*rs[j];
971 cr = r_norm / r_norm_old;
975 if ( PrtLvl >
PRINT_NONE ) ITS_FINAL(iter,MaxIt,r_norm/den_norm);
988 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
1027 const REAL tol,
const REAL abstol,
const INT MaxIt,
1031 const INT min_iter = 0;
1037 const REAL cr_max = 0.99;
1038 const REAL cr_min = 0.174;
1045 REAL r_norm, b_norm, den_norm;
1046 REAL epsilon, gamma, t;
1048 REAL *c = NULL, *s = NULL, *rs = NULL;
1049 REAL *norms = NULL, *r = NULL;
1050 REAL **p = NULL, **hh = NULL, **z=NULL;
1054 REAL r_norm_old = 0.0;
1056 INT restart_max = restart;
1057 INT restart_min = 3;
1059 INT Restart = restart;
1060 INT Restart1 = Restart + 1;
1061 LONG worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
1064 if ( PrtLvl >
PRINT_NONE ) printf(
"\nCalling VFGMRes solver (MatFree) ...\n");
1067 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
1068 printf(
"### DEBUG: maxit = %d, tol = %.4le\n", MaxIt, tol);
1075 while ( (work == NULL) && (Restart > 5) ) {
1076 Restart = Restart - 5;
1077 worksize = (Restart+4)*(Restart+n)+1-n+Restart*n;
1079 Restart1 = Restart + 1;
1082 if ( work == NULL ) {
1083 printf(
"### ERROR: No enough memory! [%s:%d]\n", __FILE__, __LINE__ );
1087 if ( PrtLvl >
PRINT_MIN && Restart < restart ) {
1088 printf(
"### WARNING: vFGMRES restart number set to %d!\n", Restart);
1096 r = work; rs = r + n; c = rs + Restart1; s = c + Restart;
1097 for (i = 0; i < Restart1; i ++) p[i] = s + Restart + i*n;
1098 for (i = 0; i < Restart1; i ++) hh[i] = p[Restart] + n + i*Restart;
1099 for (i = 0; i < Restart1; i ++) z[i] = hh[Restart] + Restart + i*n;
1110 ITS_PUTNORM(
"right-hand side", b_norm);
1111 ITS_PUTNORM(
"residual", r_norm);
1114 if (b_norm > 0.0) den_norm = b_norm;
1115 else den_norm = r_norm;
1117 epsilon = tol*den_norm;
1120 while (iter < MaxIt) {
1122 r_norm_old = r_norm;
1123 if (r_norm == 0.0) {
1136 if (cr > cr_max || iter == 0) {
1137 Restart = restart_max;
1139 else if (cr < cr_min) {
1143 if ( Restart - d > restart_min ) Restart -= d;
1144 else Restart = restart_max;
1147 if (r_norm <= epsilon && iter >= min_iter) {
1152 if (r_norm <= epsilon) {
1165 while (i < Restart && iter < MaxIt) {
1171 else pc->
fct(p[i-1], z[i-1], pc->
data);
1173 mf->
fct(mf->
data, z[i-1], p[i]);
1176 for (j = 0; j < i; j ++) {
1187 for (j = 1; j < i; ++j) {
1189 hh[j-1][i-1] = s[j-1]*hh[j][i-1] + c[j-1]*t;
1190 hh[j][i-1] = -s[j-1]*t + c[j-1]*hh[j][i-1];
1192 t= hh[i][i-1]*hh[i][i-1];
1193 t+= hh[i-1][i-1]*hh[i-1][i-1];
1195 if (gamma == 0.0) gamma = epsmac;
1196 c[i-1] = hh[i-1][i-1] / gamma;
1197 s[i-1] = hh[i][i-1] / gamma;
1198 rs[i] = -s[i-1]*rs[i-1];
1199 rs[i-1] = c[i-1]*rs[i-1];
1200 hh[i-1][i-1] = s[i-1]*hh[i][i-1] + c[i-1]*hh[i-1][i-1];
1202 r_norm = fabs(rs[i]);
1203 norms[iter] = r_norm;
1206 fasp_itinfo(PrtLvl, StopType, iter, norms[iter]/b_norm,
1207 norms[iter], norms[iter]/norms[iter-1]);
1210 fasp_itinfo(PrtLvl, StopType, iter, norms[iter], norms[iter],
1211 norms[iter]/norms[iter-1]);
1215 if (r_norm <= epsilon && iter >= min_iter)
break;
1221 rs[i-1] = rs[i-1] / hh[i-1][i-1];
1222 for (k = i-2; k >= 0; k --) {
1224 for (j = k+1; j < i; j ++) t -= hh[k][j]*rs[j];
1227 rs[k] = t / hh[k][k];
1236 if (r_norm <= epsilon && iter >= min_iter) {
1241 if (r_norm <= epsilon) {
1252 for (j = i; j > 0; j--) {
1253 rs[j-1] = -s[j-1]*rs[j];
1254 rs[j] = c[j-1]*rs[j];
1269 cr = r_norm / r_norm_old;
1273 if (PrtLvl >
PRINT_NONE) ITS_FINAL(iter,MaxIt,r_norm);
1285 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_pvfgmres(mxv_matfree *mf, dvector *b, dvector *x, precond *pc, const REAL tol, const REAL abstol, 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 REAL abstol, 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 REAL abstol, 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_dblc_pvfgmres(dBLCmat *A, dvector *b, dvector *x, precond *pc, const REAL tol, const REAL abstol, 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