// pde_nuderiv2dg_tri.java // second order pde with second degree solution // just proof of concept // generalize to fourth order, fourth degree // sufficient points must be available for each order,degree // // given a PDE, a triangularization, boundary values, // e.g. 22_ts.tri .bound .coord // Uxx(x,y)+2Uxy(x,y)+3Uyy(x,y)+4Ux(x,y)+5Uy(x,y)+6U(x,y)=f(x,y) // f(x,y)=6x^2+12xy+18y^2+42x+68y+101 // uana(x,y)=x^2+2xy+3y^2+4x+5y+6 soultion, generally not known // used to compute boundary values // used for error checking // U(xf,yf) unknown at nfree vertices, DOF // U(xb,yb) known at nbound boundary vertices, nvert total vertices // nuderiv2d determines cxx, cxy, cyy, cx, cy at a subset of vertices // Uxx(xf,yf)= cxx(xf,yf) *U(xf,yf)+ unknown U(xf,yf) m<=36 points // cxx(xfi,yfi)*U(xfi,yfi)+...+ unknown U(xfi,yfi) for each xf,yf // cxx(xbj,ybj)*U(xbj,ybj)+... known value // Uxy(xf,yf)= cxy(xf,yf) *U(xf,yf)+ unknown U(xf,yf) // cxy(xfi,yfi)*U(xfi,yfi)+...+ unknown U(xfi,yfi) // cxy(xbj,ybj)*U(xbj,ybj)+... known value // Uyy(xf,yf)= cyy(xf,yf) *U(xf,yf)+ unknown U(xf,yf) // cyy(xfi,yfi)*U(xfi,yfi)+...+ unknown U(xfi,yfi) // cyy(xbj,ybj)*U(xbi,ybi)+... known value // Ux (xf,yf)= cx (xf,yf) *U(xf,yf)+ unknown U(xf,yf) // cx (xfi,yfi)*U(xfi,yfi)+...+ unknown U(xfi,yfi) // cx (xbj,ybj)*U(xbi,ybi)+... known value // Uy (xf,yf)= cy (xf,yf) *U(xf,yf)+ unknown U(xf,yf) // cy (xfi,yfi)*U(xfi,yfi)+...+ unknown U(xfi,yfi) // cy (xbj,ybj)*U(xbi,ybi)+... known value // f(xf,yf) right hand side, known, computable // // substituting in the PDE, a set of linear simultaneous equations for U(xf,yf) // | a11 a12 ... a1n | |U(xf1,yf1)| = rhs(1) n = nfree // | a21 a22 ... a2n | * |U(xf2,yf2)| = rhs(2) // ... // | an1 an2 ... ann | |U(xfn,yfn)| = rhs(n) // // for cxx, cxy, ... at point xf1,yf1 a free vertex, a DOF // a11 = cxx(xf1,yf1) + 2*cxy(xf1,yf1) + 3*cyy(xf1,yf1) + // 4*cx (xf1,yf1) + 5*cy (xf1,yf1) + 6 // // a1j = cxx(xfj,yfj) + 2*cxy(xfj,yfj) + 3*cyy(xfj,yfj) + // 4*cx (xfj,yfj) + 5*cy (xfj,yfj) + 6 ip[1]=j any free xfj,yfj // // rhs(1) = f(xf1,yf1) - cxx(xbj,ybj)*U(xbj,ybj) - 2cxy(xbj,ybj) ... // ip[1]=j any bound xbj,ybj // // same code for a21, a22, ... new N.nu2d on next point // then rest of DOF points // solve for U(xfi,yfi) i=1..nfree import java.io.*; // for reading triangle data files 22_t*.tri .coord .bound class pde_nuderiv2dg_tri { // variables for reading triangles static String root; // root name for .tri, .coord, .bound final int sz = 512; final int szsz = 1024; int debug = 0; int ntri; // number of triangles int minvert; // minimum vertex number, reduced to zero int t1[] = new int[sz]; // vertex numbers on triangles int t2[] = new int[sz]; // vertex numbers on triangles int t3[] = new int[sz]; // vertex numbers on triangles int ncoord; // number of coordinates, also equals nvert double xc[] = new double[sz]; // coordinates in vertex order double yc[] = new double[sz]; // coordinates in vertex order int b1[] = new int[sz]; // dirichlet boundary edge vertices int b2[] = new int[sz]; // dirichlet boundary edge vertices double xmin, xmax, ymin, ymax; // determined by input int uniquev[] = new int[sz]; // all vertices int nvert; // number of unique vertices int uniqueb[] = new int[sz]; // bound vertices int nbound; // number of boundary vertices int uniquef[] = new int[sz]; // free vertices, 0 to nfree-1 int nfree; // degrees of freedom nvert-nbound int nuniquev, nuniqueb, nuniquef; // vertices counts pde_nuderiv2dg_tri() { int debug = 0; int m = 0; int j; int stat; int order = 2; double cx[] = new double[36]; // present limit of nuderiv2dg double cy[] = new double[36]; double cxx[] = new double[36]; double cxy[] = new double[36]; double cyy[] = new double[36]; int ip[] = new int[36]; double ap; double error, maxerror; int kind = 1; System.out.println("pde_nuderiv2dg_tri.java running"); System.out.println( "Uxx(x,y)+2Uxy(x,y)+3Uyy(x,y)+4Ux(x,y)+5Uy(x,y)+6U(x,y)=f(x,y)"); System.out.println("f(x,y)=6x^2+12xy+18y^2+42x+68y+101"); System.out.println("uana(x,y)=x^2+2xy+3y^2+4x+5y+6 solution"); stat = do_input(); if(stat != 0) System.exit(1); // can not continue nuderiv2dg N = new nuderiv2dg(); double x[] = new double[nvert]; double y[] = new double[nvert]; double U[] = new double[nvert]; double A[][] = new double[nfree][nfree]; // matrix double rhs[] = new double[nfree]; // right hand side, forcing function double ug[] = new double[nfree]; // solution computed double Ua[] = new double[nfree]; // known solution for checking // initialize vertices System.out.println("vertex, x, y"); for(int i=0; i0) System.out.println("point="+point+", i="+i+", j="+j+", ap="+ap); } else // boundary { rhs[point] -= ap*U[j]; if(debug>0) System.out.println("point="+point+", i="+i+", j="+j+", ap*U="+ (-ap*U[j])); } } // end i across cxx, cxy, cyy, ... } // end point if(debug>0) { System.out.println("A matrix and rhs"); for(int i=0; i2) System.out.println("finding unique of nold="+nold); sortint(nold,a); j=0; for(i=1; ia[i-1]) { j++; a[j]=a[i]; } } j++; if(debug>2) System.out.println("found unique of n="+j); return j; } // end uniqueint void sortint(int n, int a[]) { int i, j, temp; for(i=0; ia[j]) {temp=a[i]; a[i]=a[j]; a[j]=temp;} } // end sortint int freevert(int c[], int na, int a[], int nb, int b[]) { // a and b sorted integer arrays, c will be from a, not in b int ia=0; int ib=0; int ic=0; if(debug>2) System.out.println("freevert na="+na+", nb="+nb); while(true) { if(ib>=nb || a[ia]!=b[ib]) {c[ic]=a[ia]; ic++; ia++;} else {ia++; ib++;} if(ia>=na) break; } if(debug>2) System.out.println("freevert nc free = "+ic); return ic; } boolean not_in(int i, int a[], int n) { boolean found = false; int j; for(j=0; j0) System.out.println(input_line); // have a line, extract 3 integers len = input_line.length(); if(len<5) // not enough data, ignore blank lines { input_line = in.readLine(); continue; } index = 0; while(input_line.substring(index,index+1).equals(" ")){index++;} last = input_line.indexOf(' ',index+1); t1[ntri] = Integer.parseInt(input_line.substring(index,last)); index = last+1; while(input_line.substring(index,index+1).equals(" ")){index++;} last = input_line.indexOf(' ',index+1); t2[ntri] = Integer.parseInt(input_line.substring(index,last)); index = last+1; while(input_line.substring(index,index+1).equals(" ")){index++;} last = input_line.indexOf(' ',index+1); if(last<1) last = len; t3[ntri] = Integer.parseInt(input_line.substring(index,last)); if(debug>0) System.out.println("tri "+ntri+" has vertices "+t1[ntri]+ " "+t2[ntri]+" "+t3[ntri]); if(t1[ntri]>nvert) nvert=t1[ntri]; if(t2[ntri]>nvert) nvert=t2[ntri]; if(t3[ntri]>nvert) nvert=t3[ntri]; if(t1[ntri]0) System.out.println(ntri+" triangles read from "+fname); nvert=nvert+1-minvert; // still must be dense sequence of numbers nuniquev=0; for(int i=0; i2) System.out.println("about to read boundary from "+fname); nbound=0; try { BufferedReader in = new BufferedReader(new FileReader(fname)); String input_line; input_line = in.readLine(); while(input_line != null) { // have a line, extract 2 integers len = input_line.length(); if(len<4) // not enough data, ignore blank lines { input_line = in.readLine(); continue; } index = 0; while(input_line.substring(index,index+1).equals(" ")){index++;} last = input_line.indexOf(' ',index+1); b1[nbound] = Integer.parseInt(input_line.substring(index,last)); index = last+1; while(input_line.substring(index,index+1).equals(" ")){index++;} last = input_line.indexOf(' ',index+1); if(last<1) last = len; b2[nbound] = Integer.parseInt(input_line.substring(index,last)); if(debug>0) System.out.println("boundary segment nbound="+nbound+ " has vertices "+b1[nbound]+", "+b2[nbound]); if(b1[nbound]>nvert) System.out.println("bad boundary vertex "+ b1[nbound]); if(b2[nbound]>nvert) System.out.println("bad boundary vertex "+ b2[nbound]); if(b1[nbound]0) System.out.println("read Dirichlet boundaries from "+fname); nuniqueb=0; for(int i=0; i0) for(int i=0; i0) System.out.println("number of free vertices is "+nuniquef); if(debug>0) for(int i=0; i2) System.out.println("about to read coordinates from "+ fname); ncoord=0; try { BufferedReader in = new BufferedReader(new FileReader(fname)); String input_line; input_line = in.readLine(); while(input_line != null) { // have a line, extract 2 double len = input_line.length(); if(len<5) // not enough data, ignore blank lines { input_line = in.readLine(); continue; } index = 0; while(input_line.substring(index,index+1).equals(" ")){index++;} last = input_line.indexOf(' ',index+1); xc[ncoord] = Double.parseDouble(input_line.substring(index,last)); index = last+1; while(input_line.substring(index,index+1).equals(" ")){index++;} last = input_line.indexOf(' ',index+1); if(last<1) last = len; yc[ncoord] = Double.parseDouble(input_line.substring(index,last)); if(debug>0) System.out.println("coordinate "+ncoord+" at "+ xc[ncoord]+", "+yc[ncoord]); if(ncoord==0) { xmax=xc[ncoord]; xmin=xc[ncoord]; ymax=yc[ncoord]; ymin=yc[ncoord]; } if(xc[ncoord]>xmax) xmax=xc[ncoord]; if(xc[ncoord]ymax) ymax=yc[ncoord]; if(yc[ncoord]0) System.out.println("coordinates read from "+fname); if(ncoord!=nvert) System.out.println("**** wrong number of coordinates="+ncoord+ ", should be"+nvert); nfree=nvert-nuniqueb; // make free vertices first if(debug>0) { System.out.println("vertex, x, y before free first"); for(int i=0; i0) root=args[0]; new pde_nuderiv2dg_tri(); } } // end class pde_nuderiv2dg_tri