// pde_abc_eq.java see WEB page for development, CMSC 455 supplemental // The PDE to be solved is: // a1(x,y)*uxx(x,y) + b1(x,y)*uxy(x,y) + c1(x,y)*uyy(x,y) + // d1(x,y)*ux(x,y) + e1(x,y)*uy(x,y) + f1(x,y)*u(x,y) = c(x,y) // // The functions and other user information is in the files: // abc.java // compile with abc.java and nderiv.java and simeq.java rderiv.java // uses simeq.java // uses deriv.java import java.text.*; class pde_abc_eq { abc ABC = new abc(); final int nd = ABC.nd; // degree of discretization final int ifcheck = ABC.ifcheck; // non zero for checking final int nx = ABC.nx; // problem parameters final int ny = ABC.ny; final double xmin = ABC.xmin; final double xmax = ABC.xmax; final double ymin = ABC.ymin; final double ymax = ABC.ymax; double us[] = new double[(nx-2)*(ny-2)]; // solution being computed double uu[] = new double[(nx-2)*(ny-2)]; // solution if checking double ut[][] = new double[(nx-2)*(ny-2)][(nx-2)*(ny-2)+1]; // equations to be solved // nx-2 by ny-2 internal, non boundary cells // all elements 0..nx-1 by 0..ny-1 includes boundary elements // xmin, xmax, ymin, ymax are defined in abc.java double hx; // x step = (xmax-xmin)/(nx-1) double hy; // y step = (ymax-ymin)/(ny-1) double hx2, hy2, hxy; // hx^2, hy^2, hx*hy int cs; // index of constant vector double pdxx[][] = new double[nd][nd]; double pdxy[][] = new double[nd][nd]; double pdyy[][] = new double[nd][nd]; double pdx[][] = new double[nd][nd]; double pdy[][] = new double[nd][nd]; double pd[][] = new double[nd][nd]; int md; // mid point correction nd/2 double error; // sum of absolute exact-computed double avgerror; // average error double maxerror; // maximum cell error DecimalFormat f6 = new DecimalFormat("0.000"); DecimalFormat f7 = new DecimalFormat(" 0.000"); DecimalFormat f8 = new DecimalFormat(" 0.000"); DecimalFormat fe = new DecimalFormat("0.000E00"); // sample System.out.println("Ua("+f6.format(xmin)+","+ nderiv N = new nderiv(); pde_abc_eq() { int i, j, ii, jj; System.out.println("pde_abc_eq.java running with user file abc.java"); md = nd/2; // mid point correction hx = (xmax-xmin)/(nx-1); // step size in x hy = (ymax-ymin)/(ny-1); // step size in y System.out.println("xmin="+f6.format(xmin)+", xmax="+f6.format(xmax)+ ", nx="+nx+", hx="+f6.format(hx)); System.out.println("ymin="+f6.format(ymin)+", ymax="+f6.format(ymax)+ ", ny="+ny+", hy="+f6.format(hy)); hx2 = hx*hx; hy2 = hy*hy; hxy = hx*hy; cs = (nx-2)*(ny-2); // constant column subscript clear(); init_matrix(); System.out.println("matrix initialized"); if(ifcheck>0) print_mat(); new simeq((nx-2)*(ny-2), ut, us); printus(); if(ifcheck>0) { printexact(); // us vector is the solution printdiff(); check(); avgerror = error/((nx-2)*(ny-2)); System.out.println("total error="+error); System.out.println("average error="+avgerror); System.out.println("max error="+maxerror); } else { // addedderivative computation on solution and check against PDE check_soln(); } check_soln(); // do it always for this demo } // end pde_abc_eq constructor void clear() { int ii; for(int i=0; i0) uu[ii] = ABC.u(xmin+(i+1)*hx,ymin+(j+1)*hy); } } } // end clear void printus() // print the computed solution { System.out.println(" computed solution"); System.out.println("us[x,y] "); for(int i=1; imaxerror) maxerror=err; } } } // end check void printexact() // typically not known { System.out.println(" exact solution"); System.out.println("u(x,y) "); for(int i=1; i1 , bye."); System.exit(1); } if(nd!=5) { System.out.println("init_matrix needs enhancement, bye."); System.exit(1); } // build discretization matrices if(ifcheck>0) { System.out.println("build_coef for point ix="+ix+", iy="+iy); } for(int i=0; i5) { System.out.println("deriv pdxx returns bb="+bb[0]+", aa="+ a[0]+" "+a[1]+" "+a[2]+" "+a[3]+" "+a[4]); } for(int i=0; i5) { System.out.println("deriv pdyy returns bb="+bb[0]+", aa="+ a[0]+" "+a[1]+" "+a[2]+" "+a[3]+" "+a[4]); } for(int j=0; j5) { System.out.println("deriv pdx returns bb="+bb[0]+", aa="+ a[0]+" "+a[1]+" "+a[2]+" "+a[3]+" "+a[4]); } for(int i=0; i5) { System.out.println("deriv pdy returns bb="+bb[0]+", aa="+ a[0]+" "+a[1]+" "+a[2]+" "+a[3]+" "+a[4]); } for(int j=0; j2) print_coef(); } // end build_coef void check_row(int row) { int ii; double sum = 0.0; for(int i=0; i0.001) System.out.println("row="+row+" is bad err="+sum); } // end check_row void build_row(int i, int j, int bi, int bj) { // i,j are in element coordinates, ir,jr are all element coord int ii, jj, ij, ir, jr, ia, ja; double p, a1c, b1c, c1c, d1c, e1c, f1c, cc; ir = i; jr = j; ii = (i-1)+(nx-2)*(j-1); // row of matrix if(ifcheck>2) System.out.println("working row "+ii+", i="+i+", j="+j+", bi="+bi+ ", bj="+bj); a1c = ABC.a1(xmin+ir*hx,ymin+jr*hy); b1c = ABC.b1(xmin+ir*hx,ymin+jr*hy); c1c = ABC.c1(xmin+ir*hx,ymin+jr*hy); d1c = ABC.d1(xmin+ir*hx,ymin+jr*hy); e1c = ABC.e1(xmin+ir*hx,ymin+jr*hy); f1c = ABC.f1(xmin+ir*hx,ymin+jr*hy); cc = ABC.c(xmin+ir*hx,ymin+jr*hy); if(ifcheck>5) { System.out.println("a1="+a1c+", b1="+b1c+", c1="+c1c); System.out.println("d1="+d1c+", e1="+e1c); System.out.println("f1="+f1c+", c="+cc); } for(int ki=0; ki2) System.out.println("working row edge i="+i+", j="+j); build_row(i, j, -1, 0); } // end j loop on edge build_coef(md+1, md, md); for(j=2; j2) System.out.println("working row edge i="+i+", j="+j); build_row(i, j, 1, 0); } // end j loop on edge build_coef(md, md-1, md); for(i=2; i2) System.out.println("working row edge i="+i+", j="+j); build_row(i, j, 0 , -1); } // end i loop on edge build_coef(md, md+1, md); for(i=2; i2) System.out.println("working row edge i="+i+", j="+j); build_row(i, j, 0 , 1); } // end i loop on edge System.out.println("four sides, one element in, special case, generated "); // now do four corners i=1; j=1; build_coef(md-1, md-1, md); build_row(i, j, -1, -1); i=1; j=ny-2; build_coef(md-1, md+1, md); build_row(i, j, -1, 1); i=nx-2; j=1; build_coef(md+1, md-1, md); build_row(i, j, 1, -1); i=nx-2; j=ny-2; build_coef(md+1, md+1, md); build_row(i, j, 1, 1); } // end init_matrix void print_mat() { System.out.println(" initial matrix "); for(int i=0; i<(nx-2)*(ny-2); i++) { System.out.println("i="+i+", j=0 .. "+((nx-2)*(ny-2))); for(int k=0; k<=(nx-2)*(ny-2); k=k+7) { for(int j=0; j<7 && j+k<=(nx-2)*(ny-2); j++) { System.out.print(f8.format(ut[i][j+k])+" "); } System.out.println(" "); } System.out.println(" "); } System.out.println(" "); } // end print_mat void check_soln() // against PDE, added later, used rderiv and xg,yg { // for all interior points double x, y, err, maxerr, avgerr, rmserr; double sumerr, sumsqerr; double cx[][] = new double[nx][nx]; double cxx[][] = new double[nx][nx]; double cy[][] = new double[ny][ny]; double cyy[][] = new double[ny][ny]; double tcxy[] = new double[ny]; double dxx, dxy, dyy, dx, dy; // a1, b1, c1, d1, e1 coefficients double xg[] = new double[nx]; // may be available double yg[] = new double[ny]; double ug[][] = new double[nx][ny]; // full, including boundaries, copied from us[] int cnt = 0; int ii; if(ifcheck>5) System.out.println("check_soln setup"); for(int i=0; i5) System.out.println("ug["+i+"]["+j+"]="+ug[i][j]); } } for(int i=0; i5) { System.out.println("cx="); for(int i=0; i5) { System.out.println("numerical dxx="+f8.format(dxx)+ ", dxy="+f8.format(dxy)+ ", dyy="+f8.format(dyy)); System.out.println("analytic dxx="+f8.format(6.0*x+6.0*y)+ ", dxy="+f8.format(6.0*x+8.0*y+5.0)+ ", dyy="+f8.format(12.0*y+8.0*x)); System.out.println("numerical dx= "+f8.format(dx)+ ", dy= "+f8.format(dy)+ ", u = "+f8.format(ug[i][j])); System.out.println("analytic dx= "+f8.format(3.0*x*x+6.0*x*y+4.0*y*y+5.0*y+6.0)+ ", dy= "+f8.format(6.0*y*y+3.0*x*x+8.0*x*y+5.0*x+7.0)+ ", u = "+f8.format(ABC.u(x,y))); } err = ABC.a1(xg[i],yg[j])*dxx + ABC.b1(xg[i],yg[j])*dxy + ABC.c1(xg[i],yg[j])*dyy + ABC.d1(xg[i],yg[j])*dx + ABC.e1(xg[i],yg[j])*dy + ABC.f1(xg[i],yg[j])*ug[i][j] - // PDE u term at i,j ABC.c(xg[i],yg[j]); // RHS err = Math.abs(err); sumerr += err; sumsqerr += err*err; maxerr = Math.max(err,maxerr); cnt++; } // end j } // end i rmserr = Math.sqrt(sumsqerr/(double)cnt); avgerr = sumerr/(double)cnt; System.out.println("check_soln values against PDE"); System.out.println("maxerr="+maxerr+", rmserr="+rmserr+ ", avgerr="+avgerr); } // end check_soln public static void main(String[] args) { new pde_abc_eq(); } } // end class pde_abc_eq