8#include <gsl/gsl_vector.h>
9#include <gsl/gsl_linalg.h>
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++)
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++)
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++)
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++)
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;
238 JFD =
dmatrix (0, ntotal - 1, 0, maxcol - 1);
239 cols =
imatrix (0, ntotal - 1, 0, maxcol - 1);
240 ncols =
ivector (0, ntotal - 1);
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));
251 for (j = 0; j <
NRELAX; j++)
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));
279 int const output,
int const itmax,
double const tol,
280 double * TP_RESTRICT
const normres)
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;
296 JFD =
dmatrix (0, ntotal - 1, 0, maxcol - 1);
297 cols =
imatrix (0, ntotal - 1, 0, maxcol - 1);
298 ncols =
ivector (0, ntotal - 1);
317 printf (
"bicgstab: itmax %d, tol %e\n", itmax, (
double)tol);
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++)
361 for (
int j = 0; j <
NRELAX; j++)
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++)
389 for (
int j = 0; j <
NRELAX; j++)
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)
441 if (fabs (rho) < rhotol)
443 if (fabs (omega) < omegatol)
454 double const tol,
int const itmax)
459 double *F, dmax, normres;
469 while (dmax > tol && it < itmax)
477 for (
int j = 0; j < ntotal; j++)
481 printf (
"Newton: it=%d \t |F|=%e\n", it, (
double)dmax);
489 for (
int j = 0; j < ntotal; j++)
502 printf (
"Newton: it=%d \t |F|=%e \n", it, (
double)dmax);
void free_derivs(derivs *v, int n)
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 F_of_v(int nvar, int n1, int n2, int n3, derivs v, double *F, derivs u)
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)
void J_times_dv(int nvar, int n1, int n2, int n3, derivs dv, double *Jdv, derivs u)
void SetMatrix_JFD(int nvar, int n1, int n2, int n3, derivs u, int *ncols, int **cols, double **Matrix)
void allocate_derivs(derivs *v, int n)
double norm_inf(double const *TP_RESTRICT const F, int const ntotal)
int Index(int ivar, int i, int j, int k, int nvar, int n1, int n2, int n3)
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.