00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "Euclid_dh.h"
00031 #include "krylov_dh.h"
00032 #include "Mem_dh.h"
00033 #include "Parser_dh.h"
00034 #include "Mat_dh.h"
00035
00036
00037 #undef __FUNC__
00038 #define __FUNC__ "bicgstab_euclid"
00039 void
00040 bicgstab_euclid (Mat_dh A, Euclid_dh ctx, double *x, double *b, int *itsOUT)
00041 {
00042 START_FUNC_DH int its, m = ctx->m;
00043 bool monitor;
00044 int maxIts = ctx->maxIts;
00045 double atol = ctx->atol, rtol = ctx->rtol;
00046
00047
00048 double alpha, alpha_1,
00049 beta_1,
00050 widget, widget_1, rho_1, rho_2, s_norm, eps, exit_a, b_iprod, r_iprod;
00051
00052
00053 double *t, *s, *s_hat, *v, *p, *p_hat, *r, *r_hat;
00054
00055 monitor = Parser_dhHasSwitch (parser_dh, "-monitor");
00056
00057
00058 t = (double *) MALLOC_DH (m * sizeof (double));
00059 s = (double *) MALLOC_DH (m * sizeof (double));
00060 s_hat = (double *) MALLOC_DH (m * sizeof (double));
00061 v = (double *) MALLOC_DH (m * sizeof (double));
00062 p = (double *) MALLOC_DH (m * sizeof (double));
00063 p_hat = (double *) MALLOC_DH (m * sizeof (double));
00064 r = (double *) MALLOC_DH (m * sizeof (double));
00065 r_hat = (double *) MALLOC_DH (m * sizeof (double));
00066
00067
00068 Mat_dhMatVec (A, x, s);
00069 CopyVec (m, b, r);
00070 Axpy (m, -1.0, s, r);
00071 CopyVec (m, r, r_hat);
00072
00073
00074 b_iprod = InnerProd (m, b, b);
00075 CHECK_V_ERROR;
00076 exit_a = atol * atol * b_iprod;
00077 CHECK_V_ERROR;
00078 eps = rtol * rtol * b_iprod;
00079
00080 its = 0;
00081 while (1)
00082 {
00083 ++its;
00084 rho_1 = InnerProd (m, r_hat, r);
00085 if (rho_1 == 0)
00086 {
00087 SET_V_ERROR ("(r_hat . r) = 0; method fails");
00088 }
00089
00090 if (its == 1)
00091 {
00092 CopyVec (m, r, p);
00093 CHECK_V_ERROR;
00094 }
00095 else
00096 {
00097 beta_1 = (rho_1 / rho_2) * (alpha_1 / widget_1);
00098
00099
00100 Axpy (m, -widget_1, v, p);
00101 CHECK_V_ERROR;
00102 ScaleVec (m, beta_1, p);
00103 CHECK_V_ERROR;
00104 Axpy (m, 1.0, r, p);
00105 CHECK_V_ERROR;
00106 }
00107
00108
00109 Euclid_dhApply (ctx, p, p_hat);
00110 CHECK_V_ERROR;
00111
00112
00113 Mat_dhMatVec (A, p_hat, v);
00114 CHECK_V_ERROR;
00115
00116
00117 {
00118 double tmp = InnerProd (m, r_hat, v);
00119 CHECK_V_ERROR;
00120 alpha = rho_1 / tmp;
00121 }
00122
00123
00124 CopyVec (m, r, s);
00125 CHECK_V_ERROR;
00126 Axpy (m, -alpha, v, s);
00127 CHECK_V_ERROR;
00128
00129
00130
00131
00132
00133 s_norm = InnerProd (m, s, s);
00134 if (s_norm < exit_a)
00135 {
00136 SET_INFO ("reached absolute stopping criteria");
00137 break;
00138 }
00139
00140
00141 Euclid_dhApply (ctx, s, s_hat);
00142 CHECK_V_ERROR;
00143
00144
00145 Mat_dhMatVec (A, s_hat, t);
00146 CHECK_V_ERROR;
00147
00148
00149 {
00150 double tmp1, tmp2;
00151 tmp1 = InnerProd (m, t, s);
00152 CHECK_V_ERROR;
00153 tmp2 = InnerProd (m, t, t);
00154 CHECK_V_ERROR;
00155 widget = tmp1 / tmp2;
00156 }
00157
00158
00159 Axpy (m, alpha, p_hat, x);
00160 CHECK_V_ERROR;
00161 Axpy (m, widget, s_hat, x);
00162 CHECK_V_ERROR;
00163
00164
00165 CopyVec (m, s, r);
00166 CHECK_V_ERROR;
00167 Axpy (m, -widget, t, r);
00168 CHECK_V_ERROR;
00169
00170
00171
00172
00173 r_iprod = InnerProd (m, r, r);
00174 CHECK_V_ERROR;
00175 if (r_iprod < eps)
00176 {
00177 SET_INFO ("stipulated residual reduction achieved");
00178 break;
00179 }
00180
00181
00182 if (monitor && myid_dh == 0)
00183 {
00184 fprintf (stderr, "[it = %i] %e\n", its, sqrt (r_iprod / b_iprod));
00185 }
00186
00187
00188 rho_2 = rho_1;
00189 widget_1 = widget;
00190 alpha_1 = alpha;
00191
00192 if (its >= maxIts)
00193 {
00194 its = -its;
00195 break;
00196 }
00197 }
00198
00199 *itsOUT = its;
00200
00201 FREE_DH (t);
00202 FREE_DH (s);
00203 FREE_DH (s_hat);
00204 FREE_DH (v);
00205 FREE_DH (p);
00206 FREE_DH (p_hat);
00207 FREE_DH (r);
00208 FREE_DH (r_hat);
00209 END_FUNC_DH}
00210
00211 #undef __FUNC__
00212 #define __FUNC__ "cg_euclid"
00213 void
00214 cg_euclid (Mat_dh A, Euclid_dh ctx, double *x, double *b, int *itsOUT)
00215 {
00216 START_FUNC_DH int its, m = A->m;
00217 double *p, *r, *s;
00218 double alpha, beta, gamma, gamma_old, eps, bi_prod, i_prod;
00219 bool monitor;
00220 int maxIts = ctx->maxIts;
00221
00222 double rtol = ctx->rtol;
00223
00224 monitor = Parser_dhHasSwitch (parser_dh, "-monitor");
00225
00226
00227
00228 bi_prod = InnerProd (m, b, b);
00229 CHECK_V_ERROR;
00230 eps = (rtol * rtol) * bi_prod;
00231
00232 p = (double *) MALLOC_DH (m * sizeof (double));
00233 s = (double *) MALLOC_DH (m * sizeof (double));
00234 r = (double *) MALLOC_DH (m * sizeof (double));
00235
00236
00237 Mat_dhMatVec (A, x, r);
00238 CHECK_V_ERROR;
00239 ScaleVec (m, -1.0, r);
00240 CHECK_V_ERROR;
00241 Axpy (m, 1.0, b, r);
00242 CHECK_V_ERROR;
00243
00244
00245 Euclid_dhApply (ctx, r, p);
00246 CHECK_V_ERROR;
00247
00248
00249 gamma = InnerProd (m, r, p);
00250 CHECK_V_ERROR;
00251
00252 its = 0;
00253 while (1)
00254 {
00255 ++its;
00256
00257
00258 Mat_dhMatVec (A, p, s);
00259 CHECK_V_ERROR;
00260
00261
00262 {
00263 double tmp = InnerProd (m, s, p);
00264 CHECK_V_ERROR;
00265 alpha = gamma / tmp;
00266 gamma_old = gamma;
00267 }
00268
00269
00270 Axpy (m, alpha, p, x);
00271 CHECK_V_ERROR;
00272
00273
00274 Axpy (m, -alpha, s, r);
00275 CHECK_V_ERROR;
00276
00277
00278 Euclid_dhApply (ctx, r, s);
00279 CHECK_V_ERROR;
00280
00281
00282 gamma = InnerProd (m, r, s);
00283 CHECK_V_ERROR;
00284
00285
00286 i_prod = InnerProd (m, r, r);
00287 CHECK_V_ERROR;
00288
00289 if (monitor && myid_dh == 0)
00290 {
00291 fprintf (stderr, "iter = %i rel. resid. norm: %e\n", its,
00292 sqrt (i_prod / bi_prod));
00293 }
00294
00295
00296 if (i_prod < eps)
00297 break;
00298
00299
00300 beta = gamma / gamma_old;
00301
00302
00303 ScaleVec (m, beta, p);
00304 CHECK_V_ERROR;
00305 Axpy (m, 1.0, s, p);
00306 CHECK_V_ERROR;
00307
00308 if (its >= maxIts)
00309 {
00310 its = -its;
00311 break;
00312 }
00313 }
00314
00315 *itsOUT = its;
00316
00317 FREE_DH (p);
00318 FREE_DH (s);
00319 FREE_DH (r);
00320 END_FUNC_DH}