8 #include <gsl/gsl_vector.h>
9 #include <gsl/gsl_linalg.h>
13 using namespace Utilities;
28 for (
int j = 0;
j < ntotal;
j++)
29 if (fabs (F[
j]) > dmax1)
40 double const * TP_RESTRICT
const dv,
41 double const * TP_RESTRICT
const rhs,
42 int const * TP_RESTRICT
const ncols,
43 int const * TP_RESTRICT
const * TP_RESTRICT
const cols,
44 double const * TP_RESTRICT
const * TP_RESTRICT
const JFD)
46 for (
int i = 0; i < ntotal; i++)
49 for (
int m = 0; m < ncols[i]; m++)
50 JFDdv_i += JFD[i][m] * dv[cols[i][m]];
51 res[i] = rhs[i] - JFDdv_i;
58 int const j,
int const k,
int const nvar,
59 int const n1,
int const n2,
int const n3,
60 double const * TP_RESTRICT
const rhs,
61 int const * TP_RESTRICT
const ncols,
62 int const * TP_RESTRICT
const * TP_RESTRICT
const cols,
63 double const * TP_RESTRICT
const * TP_RESTRICT
const JFD)
65 int i, m, Ic, Ip, Im, col, ivar;
67 gsl_vector *diag = gsl_vector_alloc(n1);
68 gsl_vector *e = gsl_vector_alloc(n1-1);
69 gsl_vector *
f = gsl_vector_alloc(n1-1);
70 gsl_vector *
b = gsl_vector_alloc(n1);
71 gsl_vector *
x = gsl_vector_alloc(n1);
73 for (ivar = 0; ivar < nvar; ivar++)
75 gsl_vector_set_zero(diag);
76 gsl_vector_set_zero(e);
77 gsl_vector_set_zero(
f);
78 for (i = 0; i < n1; i++)
80 Ip = Index (ivar, i + 1,
j, k, nvar, n1, n2, n3);
81 Ic = Index (ivar, i,
j, k, nvar, n1, n2, n3);
82 Im = Index (ivar, i - 1,
j, k, nvar, n1, n2, n3);
83 gsl_vector_set(
b,i,rhs[Ic]);
84 for (m = 0; m < ncols[Ic]; m++)
87 if (col != Ip && col != Ic && col != Im)
88 *gsl_vector_ptr(
b, i) -= JFD[Ic][m] * dv[col];
91 if (col == Im && i > 0)
92 gsl_vector_set(
f,i-1,JFD[Ic][m]);
94 gsl_vector_set(diag,i,JFD[Ic][m]);
95 if (col == Ip && i < n1-1)
96 gsl_vector_set(e,i,JFD[Ic][m]);
100 gsl_linalg_solve_tridiag(diag, e,
f,
b,
x);
101 for (i = 0; i < n1; i++)
103 Ic = Index (ivar, i,
j, k, nvar, n1, n2, n3);
104 dv[Ic] = gsl_vector_get(
x, i);
108 gsl_vector_free(diag);
118 int const i,
int const k,
int const nvar,
119 int const n1,
int const n2,
int const n3,
120 double const * TP_RESTRICT
const rhs,
121 int const * TP_RESTRICT
const ncols,
122 int const * TP_RESTRICT
const * TP_RESTRICT
const cols,
123 double const * TP_RESTRICT
const * TP_RESTRICT
const JFD)
125 int j, m, Ic, Ip, Im, col, ivar;
127 gsl_vector *diag = gsl_vector_alloc(n2);
128 gsl_vector *e = gsl_vector_alloc(n2-1);
129 gsl_vector *
f = gsl_vector_alloc(n2-1);
130 gsl_vector *
b = gsl_vector_alloc(n2);
131 gsl_vector *
x = gsl_vector_alloc(n2);
133 for (ivar = 0; ivar < nvar; ivar++)
135 gsl_vector_set_zero(diag);
136 gsl_vector_set_zero(e);
137 gsl_vector_set_zero(
f);
138 for (
j = 0;
j < n2;
j++)
140 Ip = Index (ivar, i,
j + 1, k, nvar, n1, n2, n3);
141 Ic = Index (ivar, i,
j, k, nvar, n1, n2, n3);
142 Im = Index (ivar, i,
j - 1, k, nvar, n1, n2, n3);
143 gsl_vector_set(
b,
j,rhs[Ic]);
144 for (m = 0; m < ncols[Ic]; m++)
147 if (col != Ip && col != Ic && col != Im)
148 *gsl_vector_ptr(
b,
j) -= JFD[Ic][m] * dv[col];
151 if (col == Im &&
j > 0)
152 gsl_vector_set(
f,
j-1,JFD[Ic][m]);
154 gsl_vector_set(diag,
j,JFD[Ic][m]);
155 if (col == Ip &&
j < n2-1)
156 gsl_vector_set(e,
j,JFD[Ic][m]);
160 gsl_linalg_solve_tridiag(diag, e,
f,
b,
x);
161 for (
j = 0;
j < n2;
j++)
163 Ic = Index (ivar, i,
j, k, nvar, n1, n2, n3);
164 dv[Ic] = gsl_vector_get(
x,
j);
167 gsl_vector_free(diag);
177 int const nvar,
int const n1,
int const n2,
int const n3,
178 double const * TP_RESTRICT
const rhs,
179 int const * TP_RESTRICT
const ncols,
180 int const * TP_RESTRICT
const * TP_RESTRICT
const cols,
181 double const * TP_RESTRICT
const * TP_RESTRICT
const JFD)
185 for (k = 0; k < n3; k = k + 2)
190 for (i = 2; i < n1; i = i + 2)
191 LineRelax_be (dv, i, k, nvar, n1, n2, n3, rhs, ncols, cols, JFD);
193 for (i = 1; i < n1; i = i + 2)
194 LineRelax_be (dv, i, k, nvar, n1, n2, n3, rhs, ncols, cols, JFD);
196 for (
j = 1;
j < n2;
j =
j + 2)
197 LineRelax_al (dv,
j, k, nvar, n1, n2, n3, rhs, ncols, cols, JFD);
199 for (
j = 0;
j < n2;
j =
j + 2)
200 LineRelax_al (dv,
j, k, nvar, n1, n2, n3, rhs, ncols, cols, JFD);
203 for (k = 1; k < n3; k = k + 2)
208 for (i = 0; i < n1; i = i + 2)
209 LineRelax_be (dv, i, k, nvar, n1, n2, n3, rhs, ncols, cols, JFD);
211 for (i = 1; i < n1; i = i + 2)
212 LineRelax_be (dv, i, k, nvar, n1, n2, n3, rhs, ncols, cols, JFD);
214 for (
j = 1;
j < n2;
j =
j + 2)
215 LineRelax_al (dv,
j, k, nvar, n1, n2, n3, rhs, ncols, cols, JFD);
217 for (
j = 0;
j < n2;
j =
j + 2)
218 LineRelax_al (dv,
j, k, nvar, n1, n2, n3, rhs, ncols, cols, JFD);
229 int ntotal = n1 * n2 * n3 * nvar, **cols, *ncols, maxcol =
231 double *F, *res, **JFD;
236 allocate_derivs (&
u, ntotal);
238 JFD =
dmatrix (0, ntotal - 1, 0, maxcol - 1);
239 cols =
imatrix (0, ntotal - 1, 0, maxcol - 1);
240 ncols =
ivector (0, ntotal - 1);
242 F_of_v (nvar, n1, n2, n3,
v, F,
u);
244 SetMatrix_JFD (nvar, n1, n2, n3,
u, ncols, cols, JFD);
246 for (
j = 0;
j < ntotal;
j++)
248 resid (res, ntotal, dv, F, ncols, cols, JFD);
249 printf (
"Before: |F|=%20.15e\n", (
double)
norm1 (res, ntotal));
253 relax (dv, nvar, n1, n2, n3, F, ncols, cols, JFD);
256 resid (res, ntotal, dv, F, ncols, cols, JFD);
257 printf (
"j=%d\t |F|=%20.15e\n",
j, (
double)
norm1 (res, ntotal));
262 resid (res, ntotal, dv, F, ncols, cols, JFD);
263 printf (
"After: |F|=%20.15e\n", (
double)
norm1 (res, ntotal));
268 free_derivs (&
u, ntotal);
279 int const output,
int const itmax,
double const tol,
280 double * TP_RESTRICT
const normres)
283 int ntotal = n1 * n2 * n3 * nvar, ii;
284 double alpha = 0, beta = 0;
285 double rho = 0, rho1 = 1, rhotol = 1e-50;
286 double omega = 0, omegatol = 1e-50;
287 double *
p, *rt, *
s, *
t, *r, *vv;
294 allocate_derivs (&
u, ntotal);
296 JFD =
dmatrix (0, ntotal - 1, 0, maxcol - 1);
297 cols =
imatrix (0, ntotal - 1, 0, maxcol - 1);
298 ncols =
ivector (0, ntotal - 1);
300 F_of_v (nvar, n1, n2, n3,
v, F,
u);
301 SetMatrix_JFD (nvar, n1, n2, n3,
u, ncols, cols, JFD);
306 allocate_derivs (&ph, ntotal);
310 allocate_derivs (&sh, ntotal);
317 printf (
"bicgstab: itmax %d, tol %e\n", itmax, (
double)tol);
322 J_times_dv (nvar, n1, n2, n3, dv, r,
u);
323 for (
int j = 0;
j < ntotal;
j++)
324 rt[
j] = r[
j] = F[
j] - r[
j];
326 *normres =
norm2 (r, ntotal);
328 printf (
"bicgstab: %5d %10.3e\n", 0, (
double) *normres);
336 for (ii = 0; ii < itmax; ii++)
339 if (fabs (
rho) < rhotol)
346 for (
int j = 0;
j < ntotal;
j++)
351 beta = (
rho / rho1) * (alpha / omega);
353 for (
int j = 0;
j < ntotal;
j++)
354 p[
j] = r[
j] + beta * (
p[
j] - omega * vv[
j]);
359 for (
int j = 0;
j < ntotal;
j++)
362 relax (ph.
d0, nvar, n1, n2, n3,
p, ncols, cols, JFD);
364 J_times_dv (nvar, n1, n2, n3, ph, vv,
u);
367 for (
int j = 0;
j < ntotal;
j++)
368 s[
j] = r[
j] - alpha * vv[
j];
371 *normres =
norm2 (
s, ntotal);
375 for (
int j = 0;
j < ntotal;
j++)
376 dv.
d0[
j] += alpha * ph.
d0[
j];
378 printf (
"bicgstab: %5d %10.3e %10.3e %10.3e %10.3e\n",
379 ii + 1, (
double) *normres, (
double)alpha, (
double)beta, (
double)omega);
387 for (
int j = 0;
j < ntotal;
j++)
390 relax (sh.
d0, nvar, n1, n2, n3,
s, ncols, cols, JFD);
392 J_times_dv (nvar, n1, n2, n3, sh,
t,
u);
397 for (
int j = 0;
j < ntotal;
j++)
399 dv.
d0[
j] += alpha * ph.
d0[
j] + omega * sh.
d0[
j];
400 r[
j] =
s[
j] - omega *
t[
j];
403 *normres =
norm2 (r, ntotal);
405 printf (
"bicgstab: %5d %10.3e %10.3e %10.3e %10.3e\n",
406 ii + 1, (
double) *normres, (
double)alpha, (
double)beta, (
double)omega);
412 if (fabs (omega) < omegatol)
421 free_derivs (&ph, ntotal);
425 free_derivs (&sh, ntotal);
430 free_derivs (&
u, ntotal);
441 if (fabs (
rho) < rhotol)
443 if (fabs (omega) < omegatol)
454 double const tol,
int const itmax)
458 int ntotal = n1 * n2 * n3 * nvar, ii, it;
459 double *F, dmax, normres;
463 allocate_derivs (&dv, ntotal);
464 allocate_derivs (&
u, ntotal);
469 while (dmax > tol && it < itmax)
473 F_of_v (nvar, n1, n2, n3,
v, F,
u);
474 dmax = norm_inf (F, ntotal);
477 for (
int j = 0;
j < ntotal;
j++)
481 printf (
"Newton: it=%d \t |F|=%e\n", it, (
double)dmax);
482 printf (
"bare mass: mp=%g \t mm=%g\n", (
double) par_m_plus, (
double) par_m_minus);
487 bicgstab (nvar, n1, n2, n3,
v, dv, verbose, 100, dmax * 1.e-3, &normres);
489 for (
int j = 0;
j < ntotal;
j++)
491 F_of_v (nvar, n1, n2, n3,
v, F,
u);
492 dmax = norm_inf (F, ntotal);
497 F_of_v (nvar, n1, n2, n3,
v, F,
u);
498 dmax = norm_inf (F, ntotal);
502 printf (
"Newton: it=%d \t |F|=%e \n", it, (
double)dmax);
507 free_derivs (&dv, ntotal);
508 free_derivs (&
u, ntotal);
int bicgstab(int const nvar, int const n1, int const n2, int const n3, derivs v, derivs dv, int const output, int const itmax, double const tol, double *TP_RESTRICT const normres)
void Newton(int nvar, int n1, int n2, int n3, derivs v, double tol, int itmax)
void relax(double *TP_RESTRICT const dv, int const nvar, int const n1, int const n2, int const n3, double const *TP_RESTRICT const rhs, int const *TP_RESTRICT const ncols, int const *TP_RESTRICT const *TP_RESTRICT const cols, double const *TP_RESTRICT const *TP_RESTRICT const JFD)
void LineRelax_be(double *TP_RESTRICT const dv, int const i, int const k, int const nvar, int const n1, int const n2, int const n3, double const *TP_RESTRICT const rhs, int const *TP_RESTRICT const ncols, int const *TP_RESTRICT const *TP_RESTRICT const cols, double const *TP_RESTRICT const *TP_RESTRICT const JFD)
void resid(double *TP_RESTRICT const res, int const ntotal, double const *TP_RESTRICT const dv, double const *TP_RESTRICT const rhs, int const *TP_RESTRICT const ncols, int const *TP_RESTRICT const *TP_RESTRICT const cols, double const *TP_RESTRICT const *TP_RESTRICT const JFD)
void LineRelax_al(double *TP_RESTRICT const dv, int const j, int const k, int const nvar, int const n1, int const n2, int const n3, double const *TP_RESTRICT const rhs, int const *TP_RESTRICT const ncols, int const *TP_RESTRICT const *TP_RESTRICT const cols, double const *TP_RESTRICT const *TP_RESTRICT const JFD)
double norm_inf(double const *TP_RESTRICT const F, int const ntotal)
void TestRelax(int nvar, int n1, int n2, int n3, derivs v, double *dv)
double norm2(double *v, int n)
double * dvector(long nl, long nh)
void free_dvector(double *v, long nl, long nh)
double norm1(double *v, int n)
double scalarproduct(double *v, double *w, int n)
void free_ivector(int *v, long nl, long nh)
int * ivector(long nl, long nh)
double ** dmatrix(long nrl, long nrh, long ncl, long nch)
void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch)
void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch)
int ** imatrix(long nrl, long nrh, long ncl, long nch)
This file contains aliases for making access to the long state vector Q as used eg.