/* pde_laplace.c uniform grid boundary value PDE */ /* known solution for(testing method */ /* u(x,y) = cos(k*x)*cosh(k*y) */ /* */ /* Laplace differential equation to solve */ /* d^2u/dx^2 + d^2u/dy^2 = c(x,y) = 0 */ /* */ /* uniform grid on rectangle 0 to 1, 0 to 1 */ /* set up and solve system of linear equations */ #include #include #include #include "mpf_nuderivd.h" #define digits 100 #include "simeq.h" #undef abs #define abs(x) ((x)<0.0?(-(x)):(x)) #define nx 17 /* including boundary at 0 and nx-1, 0..ny-1 */ #define ny 17 /* including boundary at 0 and ny-1, 0..ny-1 */ static double xmin = 0.0; static double xmax = 1.0; static double ymin = 0.0; static double ymax = 1.0; static double hx, hy; static double k=6.28; #define neqn (nx-2)*(ny-2) /* DOF number of equations */ #define cs neqn /* RHS */ static double xg[nx]; static double yg[ny]; /* nx-2 by ny-2 internal, non boundary cells */ static double cxx[nx]; static double cyy[ny]; static double us[neqn]; /* solution vector */ static double ut[neqn*(neqn+1)]; /* includes RHS */ static double U(double x, double y) { /* solution for(boundary and optional check */ return cos(k*x)*cosh(k*y); } /* end U */ static double c(double x, double y) { /* RHS of differential equation to solve */ /* d^2u/dx^2 + d^2u/dy^2 = c(x,y) = 0 */ return 0.0; } /* end c */ static int S(int i, int j) /* zero based index includes boundary */ { /* this is row of ut[] */ return (i-1)*(ny-2)+(j-1); /* index into us and ut, RHS, no boundary */ } /* end S */ static int SS(int i, int j, int ii, int jj) /* zero based index includes boundary */ { return S(i,j)*(neqn+1)+S(ii,jj); /* ut[], RHS, no boundary */ } /* end SS */ static void print() { double error = 0.0; double max_error = 0.0; double avg_error = 0.0; double val; int i, j; printf("\n"); printf("exact solution u, computed us, error\n"); for(i=0; i max_error) max_error = error; } printf("xg[%2d]=%7.5f, yg[%2d]=%7.5f, u=%15.6e, us=%15.6e, err=%15.6e\n", i, xg[i], j, yg[j], U(xg[i],yg[j]), val, error); } } printf("avg_error=%g, max_error=%g\n", avg_error/(double)neqn, max_error); } /* end print */ static void init_matrix() { int i, j, ii, jj, k, kj, ik; /* cs is RHS, constant column subscript */ /* zero internal cells */ for(i=1; i0.001) { printf("row i=%2d, j=%2d, is bad err=%g\n", i, j, sum); } } /* j */ } /*i */ } /* end check_rows */ static void check_soln() /* check when solution unknown */ { double smaxerr, err, x, y, uxx, uyy; int i, j, ii, jj, k; /* ux(x,y) + uy(x,y) = c(x,y) */ printf("check_soln against PDE\n"); smaxerr = 0.0; for(i=1; i smaxerr) smaxerr = abs(err); } /* ii y */ } /* i x */ printf("check soln against PDE max error=%g\n", smaxerr); } /* end Check_Soln */ /* write_soln2 for gnuplot */ static void write_soln2(double Ux[], char file_name[]) { FILE * Fout; int i, j; Fout = fopen(file_name, "w"); if(Fout==NULL) { printf("ERROR unable to open %s for writing \n", file_name); exit(1); } printf("writing %s\n", file_name); for(i=0; i