/* pde3_eq.c just checking second order approximation */ /* u(x,y) = x^3 + y^3 + 2x^2y + 3xy^2 + 4x + 5y + 6 */ /* du/dx = 3x^2 + 0 + 4xy + 3y^2 + 4 + 0 + 0 */ /* d^2u/dx^2 = 6x + 0 + 4y + 0 + 0 + 0 + 0 */ /* du/dy = 0 + 3y^2 + 2x^2 + 6xy + 0 + 5 + 0 */ /* d^2u/dy^2 = 0 + 6y + 0 + 6x + 0 + 0 + 0 */ /* */ /* solve d^2u/dx^2 + d^2u/dy^2 = 12x + 10y = c(x,y) */ /* by second order method on square -1,-1 to 1,1 */ /* second order numerical difference */ /* d^2u/dx^2 + d^2u/dy^2 = */ /* 1/h^2(u(-1h,0)+u(1h,0)+u(0,-1h)+u(0,1h)-4u(0,0)) +O(h^2) */ /* = c(x,y) */ /* solve system of linear equations for */ /* u(i-1,j)+u(i+1,j)+u(i,j-1)+u(i,j+1)-4u(i,j) = c(x,y)*h^2 */ /* see pde3_eq.txt for development */ #include #include #undef abs #define abs(a) ((a)<0.0?(-(a)):(a)) #undef min #define min(a,b) ((a)<(b)?(a):(b)) #undef max #define max(a,b) ((a)>(b)?((a):(b)) static int nx = 11; static int ny = 11; static int nn = 81; /* (nx-2)*(ny-2) */ static double ut[81][82]; /* simultaneous equations built here */ /* (nx-2)*(ny-2) by (nx-2)*(ny-2) internal, non boundary cells */ /* position is (i-1)+(nx-2)*(j-1) for internal solution u(i,j) */ /* [][(nx-2)*(ny-2)] is constant,y as in A x = y, solve for x */ static double us[81]; static const double xmin = -1.0; static const double ymin = -1.0; static const double xmax = 1.0; static const double ymax = 1.0; static double h; /* x and y step = (xmax-xmin)/(n-1) = (ymax-ymin) */ static double error; /* sum of absolute exact-computed */ static double avgerror; /* average error */ static double maxerror; /* maximum cell error */ static double u(double x, double y) /* for boundary and check */ { return x*x*x + y*y*y + 2.0*x*x*y + 3.0*x*y*y + 4.0*x + 5.0*y +6.0; } static double c(double x, double y) /* from solve */ { return 12.0*x + 10.0*y; } static void init_matrix() { int i, j, ii, jj, k; k = (nx-2)*(ny-2); /* constant column subscript */ /* zero internal cells */ for(i=1; i0) { jj = (i-1)+(nx-2)*((j-1)-1); ut[ii][jj] = 1.0; printf("jj-=%d, ", jj); } else ut[ii][k] = ut[ii][k] - u(xmin+i*h, ymin+(j-1)*h); if((i+1)<(nx-1)) { jj = ((i-1)+1)+(nx-2)*(j-1); ut[ii][jj] = 1.0; printf("jji+=%d, ", jj); } else ut[ii][k] = ut[ii][k] - u(xmin+(i+1)*h, ymin+j*h); if((i-1)!=0) { jj = ((i-1)-1)+(nx-2)*(j-1); ut[ii][jj] = 1.0; printf("jji-=%d", jj); } else ut[ii][k] = ut[ii][k] - u(xmin+(i-1)*h, ymin+j*h); printf("\n"); } } } static void check() /* typically not known, instrumentation */ { int i, j; double uexact, err; error = 0.0; maxerror = 0.0; for(i=1; imaxerror) maxerror=err; } } } static void printus() { int i, j; printf("\n computed solution\n"); for(i=1; i abs_pivot) { i_pivot = i; pivot = B[row[i]][k]; abs_pivot = abs ( pivot ); } } /* have pivot, interchange row pointers */ hold = row[k]; row[k] = row[i_pivot]; row[i_pivot] = hold; /* check for near singular */ if( abs_pivot < 1.0E-10 ) { for(j=k+1; j