/* fem_check_abc_la.c Galerkin FEM * solve a(x,y) uxx(x,y) + b(x,y) uxy(x,y) + c(x,y) uyy(x,y) + * d(x,y) ux(x,y) + e(x,y) uy(x,y) + f(x,y) u(x,y) = c(x,y) * boundary conditions computed using u(x) in abc.c * xmin, xmax, ymin, ymax, nx, ny given in abc.h * analytic solution may be given by u(x) in abc.c, ifcheck>0 * gauss-legendre integration used * solve for Uj numerical approximation U(x_j) of u(x_j) * k * U = f, solve simultaneous equations for U */ #include #include #include #include "laphi.h" #include "simeq.h" #include "gaulegf.h" #include "abc_la.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)) static double kg[160000]; /* (i*nx+j)*ny*ny + (ii*ny+jj) */ static double xg[400]; static double yg[400]; static double fg[400]; static double ug[400]; static double Ua[400]; double F(double x, double y) /* forcing function */ { return c(x,y); } double uana(double x, double y) /* analytic solution and boundaries */ { return u(x,y); } /* i, j, nx, ii, jj, ny, needed by galk or galf, available at call */ int i, j, ii, jj; double galk(double x, double y) { /* Galerkin k stiffness function for this problem */ return (a1(x,y)*phipp(x,j,nx-1,xg)* phi(y,jj,ny-1,yg) + b1(x,y)* phip(x,j,nx-1,xg)* phip(y,jj,ny-1,yg) + c1(x,y)* phi(x,j,nx-1,xg)*phipp(y,jj,ny-1,yg) + d1(x,y)* phip(x,j,nx-1,xg)* phi(y,jj,ny-1,yg) + e1(x,y)* phi(x,j,nx-1,xg)* phip(y,jj,ny-1,yg) + f1(x,y)* phi(x,j,nx-1,xg)* phi(y,jj,ny-1,yg) )* phi(x,i,nx-1,xg)* phi(y,ii,ny-1,yg); } /* end galk used by aquad3 and other integration */ double galf(double x, double y) /* Galerkin f function for this problem */ { return F(x,y)*phi(x,i,nx-1,xg)*phi(y,ii,ny-1,yg); } /* end galf used by aquad and other integration */ int main(int argc, char *argv[]) { /* i, j and n above, used by aquad3 */ double x, y, hx, hy; double a, b, sum; double xx[100], wx[100]; /* for Gauss-Legendre */ double yy[100], wy[100]; /* for Gauss-Legendre */ double val, err, avgerr, maxerr; int px, npx, py, npy; printf("fem_check_abc_la.c running \n"); printf("Given a1 uxx + b1 uxy + c1 uyy + d1 ux + e1 uy + f1 u = \n"); printf("c(x,y) \n"); printf("xmin<=x<=xmax ymin<=y<=ymax Boundaries \n"); printf("Analytic solution u(x) = \n"); printf("xmin=%g, xmax=%g, ymin=%g, ymax=%g \n", xmin, xmax, ymin, ymax); printf("nx=%d, ny=%d \n", nx, ny); printf("x grid and analytic solution at ymin \n"); hx = (xmax-xmin)/(double)(nx-1); for(i=0; i1) printf("Legendre integration=%g, at i=%d, j=%d, ii=%d, jj=%d \n", val, i, j, ii, jj); kg[(i*ny+ii)*nx*ny+(j*ny+jj)] = val; } /* end jj loop */ } /* end ii loop */ } /* end j loop */ } /* end i loop */ /* compute integral for f(i) */ for(i=1; i1) printf("Legendre integration=%g, f at i=%d, ii=%d \n", val, i, ii); fg[i*ny+ii] = val; } } simeq(nx*ny, kg, fg, ug); if(ifcheck) { avgerr = 0.0; maxerr = 0.0; printf("ug computed Galerkin, Ua analytic, error \n"); for(i=0; imaxerr) maxerr = err; avgerr = avgerr + err; printf("ug[%d,%d]=%6.3f, Ua=%6.3f, err=%g \n", i, ii, ug[i*ny+ii], Ua[i*ny+ii], ug[i*ny+ii]-Ua[i*ny+ii]); } } printf(" maxerr=%g, avgerr=%g \n", maxerr, avgerr/(double)(nx*ny)); } else /* no ifcheck */ { printf("solution ug computed by Galerkin method \n"); for(i=0; i