// pde22_s2_eq.c uniform grid boundary value PDE // known solution for(testing method // U(x,y) = sin^2(Pi*x)*sin^2(Pi*y) // // differential equation to solve // d^2u/dx^2 + d^2u/dy^2 = Uxx(x,y) + Uyy(x,y) = c(x,y) given // Uxx(x,y) = 2*Pi^2*cos(2*Pi*x)*sin^2(Pi*y) // Uyy(x,y) = -2*Pi^2*sin^2(Pi*x)*cos(2*Pi*y) // U(x,y)=0 on boundary omega x=0, x=1, y=0, y=1 // // uniform grid on rectangle 0 to 1, 0 to 1 // set up and solve system of linear equations #include #include #include #include #include "nuderiv.h" #include "simeq.h" #undef abs #define abs(x) ((x)<0.0?(-(x)):(x)) #define Pi 3.1415926535897932384626433832795028841971 #define nx 13 // including boundary at 0 and nx-1, 0..ny-1 #define ny 13 // including boundary at 0 and ny-1, 0..nx-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; #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 sin(Pi*x)*sin(Pi*x)*sin(Pi*y)*sin(Pi*y); } // end U static double Uxx(double x, double y) { // solution for(boundary and optional check return 2.0*Pi*Pi*cos(2.0*Pi*x)*sin(Pi*y)*sin(Pi*y); } // end U static double Uyy(double x, double y) { // solution for(boundary and optional check return 2.0*Pi*Pi*sin(Pi*x)*sin(Pi*x)*cos(2.0*Pi*y); } // end U static double c(double x, double y) { // RHS of differential equation to solve return Uxx(x,y) + Uyy(x,y); } // 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