/* pde_nl13.c solve non linear second order, third degree equation * solve u^2 u'' + 2 u u' + 3u = f(x) * f(x) = (41/3)-(2116/9)x+(4780/3)x^2-(48976/9)x^3+ * 9984x^4-(88064/9)x^5+(14336/3)x^6-(8192/9)x^7 * with boundary u(0)=1, u(1)=1 0 < x < 1 * set up system of equations, use specialized Jacobian, simeq_newton3 * solution u(x) = 1.0 -(20.0/3.0)*x +12.0*x*x -(16.0/3.0)*x*x*x */ #include #include #include #include "deriv.h" #include "simeq_newton3.h" /* also needs invert.h and invert.c */ #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)) #define nx 5 /* number of equations and number of linear unknowns */ #define neqn nx /* number of nonlinear terms */ #define nlin 15 /* total number of terms */ #define ntot neqn+nlin static double k[neqn][ntot]; /* nonlinear system of equations */ static double xg[nx]; /* xgrid */ static double u[ntot]; /* unknown, except for boundary values */ static double f[neqn]; /* RHS of nonlinear equations */ static double Ua[neqn]; /* only need linear values, other terms computed */ static double cx[nx]; /* numerical first derivative */ static double cxx[nx]; /* numerical second derivative */ static double xmin = 0.0; static double xmax = 1.0; static double hx; /* linear, then nonlinear terms */ static int var1[ntot] = { 0, 1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}; static int var2[ntot] = {-1,-1,-1,-1,-1, 1, 2, 3, 2, 3, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3}; static int var3[ntot] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 2, 2, 2, 3, 3, 3}; static double F(double x) /* forcing function */ { return (41.0/3.0)-(2116.0/9.0)*x +(4780.0/3.0)*x*x - (48976.0/9.0)*x*x*x + 9984.0*x*x*x*x - (88064.0/9.0)*x*x*x*x*x + (14336.0/3.0)*x*x*x*x*x*x - (8192.0/9.0)*x*x*x*x*x*x*x; } /* end F */ /* exact solution for checking */ static double uana(double x) { return 1.0 -(20.0/3.0)*x +12.0*x*x -(16.0/3.0)*x*x*x; } /* end uana */ static void check_soln(double U[]) /* check when solution unknown */ { /* u^2 u'' + 2 u u' + 3u = f(x) check for each xg inside boundary */ int i, j; double xi, val, err, smaxerr; printf("check_soln \n"); smaxerr = 0.0; for(i=1; imaxerr) maxerr = err; avgerr = avgerr + err; printf("u[%d]=%7.4f, Ua=%7.4f, err=%g \n", i, u[i], Ua[i], u[i]-Ua[i]); } printf(" maxerr=%g, avgerr=%g \n", maxerr, avgerr/(double)nx); printf("\n"); printf("check_soln on computed solution against PDE \n"); check_soln(u); /* for use when analytic solution is not known */ printf("just checking check_soln when given correct solution \n"); check_soln(Ua); /* checking on checker */ /* try giving the correct solution, to check on solver */ printf("just checking simeq_newton3 when given correct solution \n"); u[0] = 1.0; u[1] = 0.0; u[2] = 0.0; u[3] = 0.5; u[4] = 1.0; simeq_newton3(neqn, nlin, k, f, var1, var2, var3, u, 3, 0.001, 1); printf("pde_nl13.c finished \n"); return 0; } /* end main of pde_nl13.c */