/* pde2sin_sparse_gmp.c 2d uniform grid boundary value PDE */ /* known solution for testing method */ /* u(x,y) = sin(x-y) */ /* */ /* differential equation to solve */ /* du/dx + du/dy=0 */ /* uniform grid on rectangle 0 to 2Pi, 0 to 2Pi */ /* set up and solve system of linear equations */ /* maximum error measured against analytic solution * nx ny maxerror * 13 12 1.40e-4 same as nx=12, ny=13, they can not be equal * 15 14 4.38e-6 * 17 16 1.02e-7 * 19 18 1.84e-9 * 21 20 2.70e-11 * 23 22 3.23e-13 * 25 24 3.23e-15 * 31 30 1.26e-21 */ #include int digits = 100; /* external */ #include "mpf_math.h" #include "mpf_deriv.h" #include "mpf_sparse.h" /* do NOT make nx=ny, this creates a singular matrix */ /* including boundary at 0 and nx-1, 0 and ny-1 */ #define nx 13 #define ny 12 #define neqn ((nx-2)*(ny-2)) #define cs neqn static mpf_t xmin, xmax, ymin, ymax, hx, hy; static mpf_t twopi; static mpf_t xg[nx]; static mpf_t yg[ny]; /* nx-2 by ny-2 internal, boundary cells */ static mpf_t cx[nx]; static mpf_t cy[ny]; static mpf_t coefdx, coefdy; static mpf_t us[neqn]; /* solution vector */ /* static mpf_t ut[neqn][neqn+1]; includes RHS, now sparse B */ static struct sparse B; static void u(mpf_t result, mpf_t x, mpf_t y) { /* solution for boundary and optionalcheck */ mpf_t xmy; /* x-y */ mpf_init(xmy); mpf_sub(xmy, x, y); mpf_sin(result, xmy); } /* end u */ static void c(mpf_t result, mpf_t x, mpf_t y) { /* RHS of differential equation to solve */ mpf_set_si(result, 0); } /* end c */ static int S(int i, int j) { if(i<1 || i>nx-1 || j<1 || j>ny-1) gmp_printf("BAD S i=%2d, j=%2d\n", i, j); return (i-1)*(ny-2)+(j-1); /* index into us and ut */ } /* end S */ static void print() { int i, j; mpf_t error; mpf_t max_error; mpf_t avg_error; mpf_t val, tmp; mpf_init_set_si(error, 0); mpf_init_set_si(max_error, 0); mpf_init_set_si( avg_error, 0); mpf_init(val); mpf_init(tmp); gmp_printf("\n"); gmp_printf("exact solution u, computed us, error\n"); for(i=0; i0) mpf_set(max_error, error); gmp_printf("us=%Fg \n", val); gmp_printf("err=%Fg \n", error); } } mpf_div_ui(val, avg_error, neqn); gmp_printf("avg_error=%Fg \n", val); gmp_printf("max_error=%Fg \n", max_error); } /* end print */ static void check_row(int row) /* only for checking */ { /* row is in ut solution coordinates */ int i, j, ii; mpf_t sum, val, tmp, bval; mpf_init_set_si(sum, 0); mpf_init(val); mpf_init(tmp); mpf_init(bval); for(i=1; i0) gmp_printf("BAD row=%4d, err=%Fg\n", row, sum); } /* end check_row */ static void init_matrix() { int i, j, ii, jj; int k, kj, ik; mpf_t val; mpf_init(val); /* cs is RHS, constant column subscript */ /* zero internal cells, not with sparse */ for(i=0; i0) mpf_set(smaxerr, val); } /* ii Y */ } /* i X */ gmp_printf("check_soln max error=%Fg \n", smaxerr); } /* end Check_Soln */ int main(int argc, char *argv[]) { int i, j; mpf_t tmp, val; /* pde2sin_sparse */ gmp_printf("pde2sin_sparse_gmp.c running\n"); gmp_printf("differential equation to solve\n"); gmp_printf("du/dx + du/dy = c(x,y)\n"); gmp_printf("c(x,y)=0\n"); gmp_printf("uniform grid on rectangle 0,2Pi to 0,2Pi\n"); gmp_printf("known Solution, for testing method\n"); gmp_printf("u(x,y) = sin(x-y)\n"); gmp_printf("do not make nx=ny, this creates a singular matrix\n"); mpf_init(tmp); mpf_init(val); mpf_init(twopi); mpf_twopi(twopi); mpf_init_set_si(xmin, 0); mpf_init_set(xmax, twopi); mpf_init_set_si(ymin, 0); mpf_init_set(ymax, twopi); mpf_init(hx); mpf_sub(hx, xmax, xmin); mpf_div_ui(hx, hx, nx-1); mpf_init(hy); mpf_sub(hy, ymax, ymin); mpf_div_ui(hy, hy, ny-1); for(i=0; i