/* pde4sin_nueqsp.c 4d uniform grid boundary value PDE */ /* known solution for testing method */ /* u(x,y) = sin(x-y) */ /* */ /* differential equation to solve */ /* du/dx + du/dy + du/dz + du/dt =0 */ /* uniform grid on rectangle 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 */ #include #include #include int digits = 50; /* external */ #include "mpf_math.h" #include "mpf_nuderiv.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 10 #define ny 9 #define nz 8 #define nt 7 #define neqn ((nx-2)*(ny-2)*(nz-2)*(nt-2)) #define cs neqn static mpf_t xmin, xmax, ymin, ymax, zmin, zmax, tmin, tmax; static mpf_t hx, hy, hz, ht; static mpf_t twopi; static mpf_t xg[nx]; /* index i */ static mpf_t yg[ny]; /* index ii */ static mpf_t zg[nz]; /* index iii */ static mpf_t tg[nt]; /* index iiii */ /* nx-2 by ny-2 by nz-2 by nt-2 internal, boundary cells */ static mpf_t cx[nx][nx]; static mpf_t cy[ny][ny]; static mpf_t cz[nz][nz]; static mpf_t ct[nt][nt]; static mpf_t coefdx, coefdy, coefdz, coefdt; static mpf_t us[neqn]; /* solution vector */ /*static mpf_t ut[neqn][neqn+1]; includes RHS */ static struct sparse A; static void u(mpf_t result, mpf_t x, mpf_t y, mpf_t z, mpf_t t) { /* solution for boundary and optionalcheck */ mpf_t xmy; /* x-y+z-t */ mpf_init(xmy); mpf_sub(xmy, x, y); mpf_add(xmy, xmy, z); mpf_sub(xmy, xmy, t); mpf_sin(result, xmy); } /* end u */ static void c(mpf_t result, mpf_t x, mpf_t y, mpf_t z, mpf_t t) { /* RHS of differential equation to solve */ mpf_set_si(result, 0); } /* end c */ static int S(int i, int ii, int iii, int iiii) { if(i<1 || i>nx-1 || ii<1 || ii>ny-1) gmp_printf("BAD S i=%2d, ii=%2d\n", i, ii); if(iii<1 || iii>nz-1 || iiii<1 || iiii>nt-1) gmp_printf("BAD S iii=%2d, iiii=%2d\n", iii, iiii); return (i-1)*(ny-2)*(nz-2)*(nt-2)+(ii-1)*(nz-2)*(nt-2)+ (iii-1)*(nt-2)+(iiii-1); /* index into us and ut */ } /* end S */ static void print() { int i, ii, iii, iiii; 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=1; 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 dsetup() { int i, ii, iii, iiii; for(i=0; i0) gmp_printf("BAD row=%4d, err=%Fg\n", row, sum); } /* end check_row */ static void init_matrix() { int i, j, ii, jj, iii, jjj, iiii, jjjj; int k, kk, ki, kii, kiii, kiiii; mpf_t val, utval; mpf_init(val); mpf_init(utval); /* cs is RHS, constant column subscript */ /* zero internal cells */ sparseInit(&A, neqn); gmp_printf("internal cells zeroed \n"); for(i=1; i0) mpf_set(smaxerr, val); } /* iiii T */ } /* iii Z */ } /* ii Y */ } /* i X */ gmp_printf("check_soln max error=%Fg \n", smaxerr); } /* end Check_Soln */ int main(int argc, char *argv[]) { int i, ii, iii, iiii, j, jj, jjj, jjjj; mpf_t tmp, val; double time_start, time_now; /* pde4sin_nueq */ mpf_set_default_prec(digits*3.32); time_start = (double)clock()/(double)CLOCKS_PER_SEC; gmp_printf("pde4sin_nueqsp.c running, digits=%d\n", digits); gmp_printf("differential equation to solve\n"); gmp_printf("du/dx + du/dy + du/dz + du/dt= c(x,y,z,t)\n"); gmp_printf("c(x,y,z,t)=0\n"); gmp_printf("uniform grid on rectangle 0 to 2Pi in all dimensions\n"); gmp_printf("known Solution, for testing method\n"); gmp_printf("u(x,y,z,t) = sin(x-y+z-t)\n"); gmp_printf("do not make nx=ny or any pair, this creates a singular matrix\n"); mpf_init(tmp); mpf_init(val); mpf_init(coefdx); mpf_init(coefdy); mpf_init(coefdz); mpf_init(coefdt); mpf_init(twopi); mpf_halfpi(twopi); /* two pi parallel */ mpf_init_set_si(xmin, 0); mpf_init_set(xmax, twopi); mpf_init_set_si(ymin, 0); mpf_init_set(ymax, twopi); mpf_init_set_si(zmin, 0); mpf_init_set(zmax, twopi); mpf_init_set_si(tmin, 0); mpf_init_set(tmax, 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); mpf_init(hz); mpf_sub(hz, zmax, zmin); mpf_div_ui(hz, hz, nz-1); mpf_init(ht); mpf_sub(ht, tmax, tmin); mpf_div_ui(ht, ht, nt-1); for(i=0; i