// pde44h_eq.c homogeneous Biharmonic PDE in four dimensions // solve uxxxx(x,y,z,t) + uyyyy(x,y,z,t) + uzzzz(x,y,z,t) + // utttt(x,y,z,t) + 2*uxx(x,y,z,t) + 2*uyy(x,y,z,t) + // 2*uzz(x,y,z,t) + 2*utt(x,y,z,t) + 4*u(x,y,z,t) = 0 // // boundary conditions computed using u(x,y,z,t) // analytic solution is u(x,y,z,t) = sin(x+y+z+t) // // replace continuous derivatives with discrete derivatives // solve for Uijkl numerical approximation U(x_i,y_j,z_k,t_l) // A * U = F, solve simultaneous equations for U // // The subscript versions of the derivatives are substituted into the // equation to be solved. The resulting equation is analytically solved // for u(i,j,k,l) = other u terms with coefficients and + f(xi,yj,zk,tl) // The boundaries xmin..xmax, ymin..ymax, zmin..zmax, tmin..tmax are known // The number of grid points in each dimension is known nx, ny, nz, nt // hx=(xmax-xmin)/(nx-1), hy=(ymax-ymin)/(ny-1), // hz=(zmax-zmin)/(nz-1), ht=(tmax-tmin)/(tx-1), // thus xi=xmin+i*hx, yj=ymin+j*hy, zk=zmin+k*hz, tl=tmin+l*ht // then the linear system of equations is built, // nxyzt=(nx-2)*(ny-2)*(nz-2)*(nt-2) equations because the boundary value // is known on each end. // The matrix A is nxyzt rows by nxyzt columns (nxyzt+1) columns including F // The forcing function vector F is nxyzt elements adjunct to A // The solution vector U is nxyzt elements. // The building of the A matix requires 4 nested loops for rows // i in 1..nx-1, j in 1..ny-1, k in 1..nz-1, l in 1..nt-1 for rows of A // then each term in the differential equation fills in that row // and cs = (nx-2)*(ny-2)*(nz-2)*(nt-2) the RHS, fills the last column of A // subscripting functions are used to compute linear subscripts of A, U // row=(i-1)*(ny-2)*(nz-2)*(nt-2)+(ii-1)*(nz-2)*(nt-2)+(iii-1)*(nt-2)+(iiii-1) // row*(nxyzt+1)+col for A // // care must be taken to move the negative of boundary elements to // the right hand size of the equation to be solved. These are subtracted // from the computed value of the forcing function, cs, for that row. // tests are j==0 || j==nx-1 ... jjjj==0 || jjjj==nt-1 for boundaries // #include #include #include #include #include #include "deriv.h" #include "simeq.h" #undef abs #define abs(x) ((x)<0.0?(-(x)):(x)) #undef min #define min(a,b) ((a)<(b)?(a):(b)) #undef max #define max(a,b) ((a)>(b)?(a):(b)) // nx=5 0.001 error nx=6 0.0004 error #define nx 6 #define ny 6 #define nz 6 #define nt 6 #define nxyzt (nx-2)*(ny-2)*(nz-2)*(nt-2) #define nn max(nx, max(ny, max(nz, nt))) int s(int i, int ii, int iii, int iiii) // for x,y,z,t { return (i-1)*(ny-2)*(nz-2)*(nt-2) + (ii-1)*(nz-2)*(nt-2) + (iii-1)*(nt-2) + (iiii-1); } // end s int sk(int k, int i, int ii, int iii, int iiii) // for x,y,z,t { return k*(nxyzt+1) + (i-1)*(ny-2)*(nz-2)*(nt-2) + (ii-1)*(nz-2)*(nt-2) + (iii-1)*(nt-2) + (iiii-1); } // end sk int ss(int i, int ii, int iii, int iiii, int j, int jj, int jjj, int jjjj) { return s(i,ii,iii,iiii)*(nxyzt+1) + s(j,jj,jjj,jjjj); } // end ss static double A[nxyzt*(nxyzt+1)]; // last column is RHS static double U[nxyzt]; static double xg[nx]; static double yg[ny]; static double zg[nz]; static double tg[nt]; static double Ua[nxyzt]; static double xmin = 0.0; // problem parameters static double xmax = 1.0; static double ymin = 0.0; static double ymax = 1.0; static double zmin = 0.0; static double zmax = 1.0; static double tmin = 0.0; static double tmax = 1.0; static double hx, hy, hz, ht; static double uana(double x, double y, double z, double t) //analytic solution for checking code and boundaries { return sin(x+y+z+t); } void printA() // optional { int i, ii, iii, iiii, j, jj, jjj, jjjj, cs, k; cs = nxyzt; // constant RHS column for(i=1; ismaxerr) smaxerr = err; } // end iiii } // end iii } // end ii } // end i printf("check_soln maxerr=%g \n",smaxerr); } // end check_soln void write_soln(char tag[], double u[]) // for plot4d_gl { FILE* outp; char name1[32] = "pde44h_eq_c"; char extn[] = ".dat"; char * name; int i, ii, iii, iiii; strcat(name1,tag); name = strcat(name1,extn); printf("writing solution to %s \n", name); outp = fopen(name,"w"); if(outp==NULL) { printf("ERROR unable to open %s for writing \n", name); exit(1); } fprintf(outp, "4 %2d %2d %2d %2d \n", nx, ny, nz, nt); for(i=1; imaxerr) maxerr = err; avgerr = avgerr + err; printf("ug[%d,%d,%d,%d]=%9.4f, Ua=%9.4f, err=%g \n", i, ii, iii, iiii, U[s(i,ii,iii,iiii)], Ua[s(i,ii,iii,iiii)], err); } // iiii } // iii } // ii } // i time_now = (double)clock()/(double)CLOCKS_PER_SEC; printf("total CPU time = %f seconds \n", time_now-time_start); printf("\n"); printf(" maxerr=%g, avgerr=%g \n", maxerr, avgerr/(double)(nx*ny*nz*nt)); printf("\n"); printf("end pde44h_eq.c \n"); return 0; } // end main // end pde44h_eq.c