int main(int argc, char** argv) { try { /* * Initialization code */ std::string meshFile="plateWithHole2D-1"; std::string solverFile = "nox-aztec.xml"; Sundance::setOption("meshFile", meshFile, "mesh file"); Sundance::setOption("solver", solverFile, "name of XML file for solver"); Sundance::init(&argc, &argv); // This next line is just a hack to deal with some // transitional code in the // element integration logic. Sundance::ElementIntegral::alwaysUseCofacets() = false; /* * Creation of vector type */ VectorType<double> vecType = new EpetraVectorType(); /* * Creation of mesh */ MeshType meshType = new BasicSimplicialMeshType(); MeshSource meshSrc = new ExodusMeshReader(meshFile, meshType); Mesh mesh = meshSrc.getMesh(); /* * Specification of cell filters */ CellFilter interior = new MaximalCellFilter(); CellFilter edges = new DimensionalCellFilter(1); CellFilter south = edges.labeledSubset(1); CellFilter east = edges.labeledSubset(2); CellFilter north = edges.labeledSubset(3); CellFilter west = edges.labeledSubset(4); /* * <Header level="subsubsection" name="symb_setup"> * Setup of symbolic problem description * </Header> * * Create unknown and test functions discretized on the space * first-order Lagrange polynomials. */ BasisFamily basis = new Lagrange(2); Expr u = new UnknownFunction(basis, "u"); Expr v = new TestFunction(basis, "v"); /* * Create differential operators and coordinate functions. Directions * are indexed starting from zero. The \verb+List()+ function can * collect expressions into a vector. */ Expr dx = new Derivative(0); Expr dy = new Derivative(1); Expr grad = List(dx, dy); Expr x = new CoordExpr(0); Expr y = new CoordExpr(1); /* * We need a quadrature rule for doing the integrations */ QuadratureFamily quad2 = new GaussianQuadrature(2); QuadratureFamily quad4 = new GaussianQuadrature(4); /* * Create the weak form and the BCs */ Expr source=exp(u); Expr eqn = Integral(interior, (grad*u)*(grad*v)+v*source, quad4); Expr h = new CellDiameterExpr(); Expr bc = EssentialBC(west+east, v*(u-1.0)/h, quad2); /* * <Header level="subsubsection" name="lin_prob"> * Creation of initial guess * </Header> * * So far the setup has been almost identical to that for the linear * problem, the only difference being the nonlinear term in the * equation set. */ DiscreteSpace discSpace(mesh, basis, vecType); L2Projector proj(discSpace, 1.0); Expr u0 = proj.project(); /* * <Header level="subsubsection" name="lin_prob"> * Creation of nonlinear problem * </Header> * * Similar to the setup of a \verb+LinearProblem+, the equation, BCs, * and mesh are put into a \verb+NonlinearProblem+ object which * controls the construction of the \verb+Assembler+ and its use * in building Jacobians and residuals during a nonlinear solve. */ NonlinearProblem prob(mesh, eqn, bc, v, u, u0, vecType); /* * */ ParameterXMLFileReader reader(solverFile); ParameterList solverParams = reader.getParameters(); NOXSolver solver(solverParams); prob.solve(solver); /* * Visualization output */ FieldWriter w = new VTKWriter("PoissonBoltzmannDemo2D"); w.addMesh(mesh); w.addField("soln", new ExprFieldWrapper(u0)); w.write(); /* * <Header level="subsubsection" name="postproc"> * Postprocessing * </Header> * * Postprocessing can be done using the same symbolic language * as was used for the problem specification. Here, we define * an integral giving the flux, then evaluate it on the mesh. */ Expr n = CellNormalExpr(2, "n"); Expr fluxExpr = Integral(east + west, (n*grad)*u0, quad2); double flux = evaluateIntegral(mesh, fluxExpr); Out::os() << "numerical flux = " << flux << std::endl; Expr sourceExpr = Integral(interior, exp(u0), quad4); double src = evaluateIntegral(mesh, sourceExpr); Out::os() << "numerical integrated source = " << src << std::endl; /* * Check that the flux is acceptably close to zero. This * is just a sanity check to ensure the code doesn't get completely * broken after a change to the library. */ Sundance::passFailTest(fabs(flux-src), 1.0e-3); /* * <Header level="subsubsection" name="finalize"> * Finalization boilerplate * </Header> * Finally, we have boilerplate code for exception handling * and finalization. */ } catch(std::exception& e) { Sundance::handleException(e); } Sundance::finalize(); return Sundance::testStatus(); return Sundance::testStatus(); }
/** * This example program sets up and solves the Laplace * equation \f$-\nabla^2 u=0\f$. See the * document GettingStarted.pdf for more information. */ int main(int argc, char** argv) { try { /* command-line options */ std::string meshFile="plateWithHole3D-1"; std::string solverFile = "aztec-ml.xml"; Sundance::setOption("meshFile", meshFile, "mesh file"); Sundance::setOption("solver", solverFile, "name of XML file for solver"); /* Initialize */ Sundance::init(&argc, &argv); /* --- Specify vector representation to be used --- */ VectorType<double> vecType = new EpetraVectorType(); /* --- Read mesh --- */ MeshType meshType = new BasicSimplicialMeshType(); MeshSource meshSrc = new ExodusMeshReader(meshFile, meshType); Mesh mesh = meshSrc.getMesh(); /* --- Specification of geometric regions --- */ /* Region "interior" consists of all maximal-dimension cells */ CellFilter interior = new MaximalCellFilter(); /* Identify boundary regions via labels in mesh */ CellFilter edges = new DimensionalCellFilter(2); CellFilter south = edges.labeledSubset(1); CellFilter east = edges.labeledSubset(2); CellFilter north = edges.labeledSubset(3); CellFilter west = edges.labeledSubset(4); CellFilter hole = edges.labeledSubset(5); CellFilter down = edges.labeledSubset(6); CellFilter up = edges.labeledSubset(7); /* --- Symbolic equation definition --- */ /* Test and unknown function */ BasisFamily basis = new Lagrange(1); Expr u = new UnknownFunction(basis, "u"); Expr v = new TestFunction(basis, "v"); /* Gradient operator */ Expr dx = new Derivative(0); Expr dy = new Derivative(1); Expr dz = new Derivative(2); Expr grad = List(dx, dy, dz); /* We need a quadrature rule for doing the integrations */ QuadratureFamily quad1 = new GaussianQuadrature(1); QuadratureFamily quad2 = new GaussianQuadrature(2); /** Write the weak form */ Expr eqn = Integral(interior, (grad*u)*(grad*v), quad1) + Integral(east, v, quad1); /* Write the essential boundary conditions */ Expr h = new CellDiameterExpr(); Expr bc = EssentialBC(west, v*u/h, quad2); /* Set up linear problem */ LinearProblem prob(mesh, eqn, bc, v, u, vecType); /* --- solve the problem --- */ /* Create the solver as specified by parameters in * an XML file */ LinearSolver<double> solver = LinearSolverBuilder::createSolver(solverFile); /* Solve! The solution is returned as an Expr containing a * DiscreteFunction */ Expr soln = prob.solve(solver); /* --- Postprocessing --- */ /* Project the derivative onto the P1 basis */ DiscreteSpace discSpace(mesh, List(basis, basis, basis), vecType); L2Projector proj(discSpace, grad*soln); Expr gradU = proj.project(); /* Write the solution and its projected gradient to a VTK file */ FieldWriter w = new VTKWriter("LaplaceDemo3D"); w.addMesh(mesh); w.addField("soln", new ExprFieldWrapper(soln[0])); w.addField("du_dx", new ExprFieldWrapper(gradU[0])); w.addField("du_dy", new ExprFieldWrapper(gradU[1])); w.addField("du_dz", new ExprFieldWrapper(gradU[2])); w.write(); /* Check flux balance */ Expr n = CellNormalExpr(3, "n"); CellFilter wholeBdry = east+west+north+south+up+down+hole; Expr fluxExpr = Integral(wholeBdry, (n*grad)*soln, quad1); double flux = evaluateIntegral(mesh, fluxExpr); Out::root() << "numerical flux = " << flux << std::endl; /* --- Let's compute a few other quantities, such as the centroid of * the mesh:*/ /* Coordinate functions let us build up functions of position */ Expr x = new CoordExpr(0); Expr y = new CoordExpr(1); Expr z = new CoordExpr(2); Expr xCMExpr = Integral(interior, x, quad1); Expr yCMExpr = Integral(interior, y, quad1); Expr zCMExpr = Integral(interior, z, quad1); Expr volExpr = Integral(interior, 1.0, quad1); double vol = evaluateIntegral(mesh, volExpr); double xCM = evaluateIntegral(mesh, xCMExpr)/vol; double yCM = evaluateIntegral(mesh, yCMExpr)/vol; double zCM = evaluateIntegral(mesh, zCMExpr)/vol; Out::root() << "centroid = (" << xCM << ", " << yCM << ", " << zCM << ")" << std::endl; /* Next, compute the first Fourier sine coefficient of the solution on the * surface of the hole.*/ Expr r = sqrt(x*x + y*y); Expr sinPhi = y/r; /* Use a higher-order quadrature rule for these integrals */ QuadratureFamily quad4 = new GaussianQuadrature(4); Expr fourierSin1Expr = Integral(hole, sinPhi*soln, quad4); Expr fourierDenomExpr = Integral(hole, sinPhi*sinPhi, quad2); double fourierSin1 = evaluateIntegral(mesh, fourierSin1Expr); double fourierDenom = evaluateIntegral(mesh, fourierDenomExpr); Out::root() << "fourier sin m=1 = " << fourierSin1/fourierDenom << std::endl; /* Compute the L2 norm of the solution */ Expr L2NormExpr = Integral(interior, soln*soln, quad2); double l2Norm_method1 = sqrt(evaluateIntegral(mesh, L2NormExpr)); Out::os() << "method #1: ||soln|| = " << l2Norm_method1 << endl; /* Use the L2Norm() function to do the same calculation */ double l2Norm_method2 = L2Norm(mesh, interior, soln, quad2); Out::os() << "method #2: ||soln|| = " << l2Norm_method2 << endl; /* * Check that the flux is acceptably close to zero. The flux calculation * is only O(h) so keep the tolerance loose. This * is just a sanity check to ensure the code doesn't get completely * broken after a change to the library. */ Sundance::passFailTest(fabs(flux), 1.0e-2); } catch(std::exception& e) { Sundance::handleException(e); } Sundance::finalize(); return Sundance::testStatus(); }
int main(int argc, char** argv) { try { int depth = 0; bool useCCode = false; Sundance::ElementIntegral::alwaysUseCofacets() = true; Sundance::clp().setOption("depth", &depth, "expression depth"); Sundance::clp().setOption("C", "symb", &useCCode, "Code type (C or symbolic)"); Sundance::init(&argc, &argv); /* We will do our linear algebra using Epetra */ VectorType<double> vecType = new EpetraVectorType(); /* Read the mesh */ MeshType meshType = new BasicSimplicialMeshType(); MeshSource mesher = new ExodusMeshReader("cube-0.1", meshType); Mesh mesh = mesher.getMesh(); /* Create a cell filter that will identify the maximal cells * in the interior of the domain */ CellFilter interior = new MaximalCellFilter(); CellFilter faces = new DimensionalCellFilter(2); CellFilter side1 = faces.labeledSubset(1); CellFilter side2 = faces.labeledSubset(2); CellFilter side3 = faces.labeledSubset(3); CellFilter side4 = faces.labeledSubset(4); CellFilter side5 = faces.labeledSubset(5); CellFilter side6 = faces.labeledSubset(6); /* Create unknown and test functions, discretized using second-order * Lagrange interpolants */ Expr u = new UnknownFunction(new Lagrange(1), "u"); Expr v = new TestFunction(new Lagrange(1), "v"); /* Create differential operator and coordinate functions */ Expr dx = new Derivative(0); Expr dy = new Derivative(1); Expr dz = new Derivative(2); Expr grad = List(dx, dy, dz); Expr x = new CoordExpr(0); Expr y = new CoordExpr(1); Expr z = new CoordExpr(2); /* We need a quadrature rule for doing the integrations */ QuadratureFamily quad2 = new GaussianQuadrature(2); QuadratureFamily quad4 = new GaussianQuadrature(4); /* Define the weak form */ //Expr eqn = Integral(interior, (grad*v)*(grad*u) + v, quad); Expr coeff = 1.0; #ifdef FOR_TIMING if (useCCode) { coeff = Poly(depth, x); } else { for (int i=0; i<depth; i++) { Expr t = 1.0; for (int j=0; j<depth; j++) t = t*x; coeff = coeff + 2.0*t - t - t; } } #endif Expr eqn = Integral(interior, coeff*(grad*v)*(grad*u) /*+ 2.0*v*/, quad2); /* Define the Dirichlet BC */ Expr exactSoln = x;//(x + 1.0)*x - 1.0/4.0; Expr h = new CellDiameterExpr(); WatchFlag watchBC("watch BCs"); watchBC.setParam("integration setup", 6); watchBC.setParam("integration", 6); watchBC.setParam("fill", 6); watchBC.setParam("evaluation", 6); watchBC.deactivate(); Expr bc = EssentialBC(side4, v*(u-exactSoln), quad4) + EssentialBC(side6, v*(u-exactSoln), quad4, watchBC); /* We can now set up the linear problem! */ LinearProblem prob(mesh, eqn, bc, v, u, vecType); #ifdef HAVE_CONFIG_H ParameterXMLFileReader reader(searchForFile("SolverParameters/aztec-ml.xml")); #else ParameterXMLFileReader reader("aztec-ml.xml"); #endif ParameterList solverParams = reader.getParameters(); std::cerr << "params = " << solverParams << std::endl; LinearSolver<double> solver = LinearSolverBuilder::createSolver(solverParams); Expr soln = prob.solve(solver); #ifndef FOR_TIMING DiscreteSpace discSpace(mesh, new Lagrange(1), vecType); L2Projector proj1(discSpace, exactSoln); L2Projector proj2(discSpace, soln-exactSoln); L2Projector proj3(discSpace, pow(soln-exactSoln, 2.0)); Expr exactDisc = proj1.project(); Expr errorDisc = proj2.project(); // Expr errorSqDisc = proj3.project(); std::cerr << "writing fields" << std::endl; /* Write the field in VTK format */ FieldWriter w = new VTKWriter("Poisson3d"); w.addMesh(mesh); w.addField("soln", new ExprFieldWrapper(soln[0])); w.addField("exact soln", new ExprFieldWrapper(exactDisc)); w.addField("error", new ExprFieldWrapper(errorDisc)); // w.addField("errorSq", new ExprFieldWrapper(errorSqDisc)); w.write(); std::cerr << "computing error" << std::endl; Expr errExpr = Integral(interior, pow(soln-exactSoln, 2.0), new GaussianQuadrature(4)); double errorSq = evaluateIntegral(mesh, errExpr); std::cerr << "error norm = " << sqrt(errorSq) << std::endl << std::endl; #else double errorSq = 1.0; #endif double tol = 1.0e-10; Sundance::passFailTest(sqrt(errorSq), tol); } catch(std::exception& e) { Sundance::handleException(e); } Sundance::finalize(); return Sundance::testStatus(); }