Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "Sundance.hpp"
00044 #include "PlayaNonlinearSolverBuilder.hpp"
00045
00046
00047
00048
00049
00050 int main(int argc, char** argv)
00051 {
00052 try
00053 {
00054 int nx = 32;
00055 double convTol = 1.0e-8;
00056 double lambda = 0.5;
00057 Sundance::setOption("nx", nx, "Number of elements");
00058 Sundance::setOption("tol", convTol, "Convergence tolerance");
00059 Sundance::setOption("lambda", lambda, "Lambda (parameter in Bratu's equation)");
00060
00061 Sundance::init(&argc, &argv);
00062
00063 Out::root() << "Bratu problem (lambda=" << lambda << ")" << endl;
00064 Out::root() << "Newton's method with automated linearization"
00065 << endl << endl;
00066
00067 VectorType<double> vecType = new EpetraVectorType();
00068
00069 MeshType meshType = new BasicSimplicialMeshType();
00070 MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx, meshType);
00071 Mesh mesh = mesher.getMesh();
00072
00073 CellFilter interior = new MaximalCellFilter();
00074 CellFilter sides = new DimensionalCellFilter(mesh.spatialDim()-1);
00075 CellFilter left = sides.subset(new CoordinateValueCellPredicate(0, 0.0));
00076 CellFilter right = sides.subset(new CoordinateValueCellPredicate(0, 1.0));
00077
00078 BasisFamily basis = new Lagrange(1);
00079 Expr u = new UnknownFunction(basis, "w");
00080 Expr v = new TestFunction(basis, "v");
00081
00082 Expr grad = gradient(1);
00083
00084 Expr x = new CoordExpr(0);
00085
00086 const double pi = 4.0*atan(1.0);
00087 Expr uExact = sin(pi*x);
00088 Expr R = pi*pi*uExact - lambda*exp(uExact);
00089
00090 QuadratureFamily quad4 = new GaussianQuadrature(4);
00091 QuadratureFamily quad2 = new GaussianQuadrature(2);
00092
00093 DiscreteSpace discSpace(mesh, basis, vecType);
00094 Expr uPrev = new DiscreteFunction(discSpace, 0.5);
00095
00096 Expr eqn
00097 = Integral(interior, (grad*v)*(grad*u) - v*lambda*exp(u) - v*R, quad4);
00098
00099 Expr h = new CellDiameterExpr();
00100 Expr bc = EssentialBC(left+right, v*u/h, quad2);
00101
00102 NonlinearProblem prob(mesh, eqn, bc, v, u, uPrev, vecType);
00103
00104 NonlinearSolver<double> solver
00105 = NonlinearSolverBuilder::createSolver("playa-newton-amesos.xml");
00106
00107 Out::root() << "Newton solve" << endl;
00108
00109 SolverState<double> state = prob.solve(solver);
00110
00111 TEUCHOS_TEST_FOR_EXCEPTION(state.finalState() != SolveConverged,
00112 std::runtime_error,
00113 "Nonlinear solve failed to converge: message=" << state.finalMsg());
00114
00115 Expr soln = uPrev;
00116 FieldWriter writer = new DSVWriter("AutoLinearizedBratu.dat");
00117 writer.addMesh(mesh);
00118 writer.addField("soln", new ExprFieldWrapper(soln[0]));
00119 writer.write();
00120
00121 Out::root() << "Converged!" << endl << endl;
00122
00123 double L2Err = L2Norm(mesh, interior, soln-uExact, quad4);
00124 Out::root() << "L2 Norm of error: " << L2Err << endl;
00125
00126 Sundance::passFailTest(L2Err, 1.5/((double) nx*nx));
00127 }
00128 catch(std::exception& e)
00129 {
00130 Sundance::handleException(e);
00131 }
00132 Sundance::finalize();
00133 return Sundance::testStatus();
00134 }
00135