示例#1
0
/** 
 * 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 nx = 32;
    double convTol = 1.0e-8;
    double lambda = 0.5;
    Sundance::setOption("nx", nx, "Number of elements");
    Sundance::setOption("tol", convTol, "Convergence tolerance");
    Sundance::setOption("lambda", lambda, "Lambda (parameter in Bratu's equation)");

    Sundance::init(&argc, &argv);

    Out::root() << "Bratu problem (lambda=" << lambda << ")" << endl;
    Out::root() << "Newton's method, linearized by hand" << endl << endl;

    VectorType<double> vecType = new EpetraVectorType();

    MeshType meshType = new BasicSimplicialMeshType();
    MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx, meshType);
    Mesh mesh = mesher.getMesh();

    CellFilter interior = new MaximalCellFilter();
    CellFilter sides = new DimensionalCellFilter(mesh.spatialDim()-1);
    CellFilter left = sides.subset(new CoordinateValueCellPredicate(0, 0.0));
    CellFilter right = sides.subset(new CoordinateValueCellPredicate(0, 1.0));
    
    BasisFamily basis = new Lagrange(1);
    Expr w = new UnknownFunction(basis, "w");
    Expr v = new TestFunction(basis, "v");

    Expr grad = gradient(1);

    Expr x = new CoordExpr(0);



    const double pi = 4.0*atan(1.0);
    Expr uExact = sin(pi*x);
    Expr R = pi*pi*uExact - lambda*exp(uExact);

    QuadratureFamily quad4 = new GaussianQuadrature(4);
    QuadratureFamily quad2 = new GaussianQuadrature(2);

    DiscreteSpace discSpace(mesh, basis, vecType);
    Expr uPrev = new DiscreteFunction(discSpace, 0.5);
    Expr stepVal = copyDiscreteFunction(uPrev);

    Expr eqn 
      = Integral(interior, (grad*v)*(grad*w) + (grad*v)*(grad*uPrev) 
        - v*lambda*exp(uPrev)*(1.0+w) - v*R, quad4);

    Expr h = new CellDiameterExpr();
    Expr bc = EssentialBC(left+right, v*(uPrev+w)/h, quad2); 

    LinearProblem prob(mesh, eqn, bc, v, w, vecType);

    LinearSolver<double> linSolver 
      = LinearSolverBuilder::createSolver("amesos.xml");

    Out::root() << "Newton iteration" << endl;
    int maxIters = 20;
    Expr soln ;
    bool converged = false;

    for (int i=0; i<maxIters; i++)
    {
      /* solve for the next u */
      prob.solve(linSolver, stepVal);
      Vector<double> stepVec = getDiscreteFunctionVector(stepVal);
      double deltaU = stepVec.norm2();
      Out::root() << "Iter=" << setw(3) << i << " ||Delta u||=" << setw(20)
                  << deltaU << endl;
      addVecToDiscreteFunction(uPrev, stepVec);
      if (deltaU < convTol) 
      {
        soln = uPrev;
        converged = true;
        break;
      }
    } 
    TEUCHOS_TEST_FOR_EXCEPTION(!converged, std::runtime_error, 
      "Newton iteration did not converge after " 
      << maxIters << " iterations");
    
    FieldWriter writer = new DSVWriter("HandCodedBratu.dat");
    writer.addMesh(mesh);
    writer.addField("soln", new ExprFieldWrapper(soln[0]));
    writer.write();

    Out::root() << "Converged!" << endl << endl;

    double L2Err = L2Norm(mesh, interior, soln-uExact, quad4);
    Out::root() << "L2 Norm of error: " << L2Err << endl;
    
    Sundance::passFailTest(L2Err, 1.5/((double) nx*nx));
  }
	catch(std::exception& e) 
  {
    Sundance::handleException(e);
  }
  Sundance::finalize(); 
}
int main(int argc, char** argv)
{
  try
		{
			Sundance::init(&argc, &argv);
      int np = MPIComm::world().getNProc();
      
      int nx = 64;
      const double pi = 4.0*atan(1.0);
      MeshType meshType = new BasicSimplicialMeshType();
      MeshSource mesher = new PartitionedLineMesher(0.0, pi, nx, meshType);

      Mesh mesh = mesher.getMesh();
      CellFilter interior = new MaximalCellFilter();
      CellFilter bdry = new BoundaryCellFilter();
      
      /* Create a vector space factory, used to 
       * specify the low-level linear algebra representation */
      VectorType<double> vecType = new EpetraVectorType();

      /* create symbolic coordinate functions */
      Expr x = new CoordExpr(0);

      /* create target function */
      double R = 0.01;
      Expr sx = sin(x);
      Expr cx = cos(x);
      Expr ssx = sin(sx);
      Expr sx2 = sx*sx;
      Expr cx2 = cx*cx;
      Expr f = sx2 - sx - ssx;
      Expr uStar = 2.0*R*(sx2-cx2) + R*sx2*ssx + sx;

      /* Form exact solution */
      Expr uEx = sx;
      Expr lambdaEx = R*sx2;
      Expr alphaEx = -lambdaEx/R;
      

      /* create a discrete space on the mesh */
      BasisFamily bas = new Lagrange(1);
      DiscreteSpace discreteSpace(mesh, bas, vecType);

      /* initialize the design, state, and multiplier vectors to constants */
      Expr alpha0 = new DiscreteFunction(discreteSpace, 0.25, "alpha0");
      Expr u0 = new DiscreteFunction(discreteSpace, 0.5, "u0");
      Expr lambda0 = new DiscreteFunction(discreteSpace, 0.25, "lambda0");

      /* create symbolic objects for test and unknown functions */
      Expr u = new UnknownFunction(bas, "u");
      Expr lambda = new UnknownFunction(bas, "lambda");
      Expr alpha = new UnknownFunction(bas, "alpha");

      /* create symbolic differential operators */
      Expr dx = new Derivative(0);
      Expr grad = dx;

      /* create quadrature rules of different orders */
      QuadratureFamily q1 = new GaussianQuadrature(1);
      QuadratureFamily q2 = new GaussianQuadrature(2);
      QuadratureFamily q4 = new GaussianQuadrature(4);

      /* Form objective function */
      Expr reg = Integral(interior, 0.5 * R * alpha*alpha, q2);
      Expr fit = Integral(interior, 0.5 * pow(u-uStar, 2.0), q4);

      Expr constraintEqn = Integral(interior, 
        (grad*lambda)*(grad*u) + lambda*(alpha + sin(u) + f), q4);
      Expr L = reg + fit + constraintEqn;

      Expr constraintBC = EssentialBC(bdry, lambda*u, q2);

      Functional Lagrangian(mesh, L, constraintBC, vecType);
      
      LinearSolver<double> adjSolver 
        = LinearSolverBuilder::createSolver("amesos.xml");
      ParameterXMLFileReader reader("nox-amesos.xml");
      ParameterList noxParams = reader.getParameters();
      NOXSolver nonlinSolver(noxParams);

      RCP<PDEConstrainedObjBase> obj = rcp(new NonlinearPDEConstrainedObj(
        Lagrangian, u, u0, lambda, lambda0, alpha, alpha0,
        nonlinSolver, adjSolver));

      Vector<double> xInit = obj->getInit();

      bool doFDCheck = true;
      if (doFDCheck)
      {
        Out::root() << "Doing FD check of gradient..." << endl;
        bool fdOK = obj->fdCheck(xInit, 1.0e-6, 0);
        if (fdOK) 
        {
          Out::root() << "FD check OK" << endl;
        }
        else
        {
          Out::root() << "FD check FAILED" << endl;
          TEUCHOS_TEST_FOR_EXCEPT(!fdOK);
        }
      }

      RCP<UnconstrainedOptimizerBase> opt 
          = OptBuilder::createOptimizer("basicLMBFGS.xml");
      opt->setVerb(3);

      OptState state = opt->run(obj, xInit);

      if (state.status() != Opt_Converged)
      {
        Out::root()<< "optimization failed: " << state.status() << endl;
        TEUCHOS_TEST_FOR_EXCEPT(state.status() != Opt_Converged);
      }
      else
      {
        Out::root() << "opt converged: " << state.iter() << " iterations"
                    << endl;
      }
      FieldWriter w = new MatlabWriter("NonlinControl1D");
      w.addMesh(mesh);
      w.addField("u", new ExprFieldWrapper(u0));
      w.addField("alpha", new ExprFieldWrapper(alpha0));
      w.addField("lambda", new ExprFieldWrapper(lambda0));
      w.write();

      double uErr = L2Norm(mesh, interior, u0-uEx, q4);
      double lamErr = L2Norm(mesh, interior, lambda0-lambdaEx, q4);
      double aErr = L2Norm(mesh, interior, alpha0-alphaEx, q4);
      Out::root() << "error in u = " << uErr << endl;
      Out::root() << "error in lambda = " << lamErr << endl;
      Out::root() << "error in alpha = " << aErr << endl;

      double tol = 0.05;
      Sundance::passFailTest(uErr + lamErr + aErr, tol);
    }
	catch(exception& e)
		{
      cerr << "main() caught exception: " << e.what() << endl;
		}
	Sundance::finalize();
  return Sundance::testStatus(); 
}
int main(int argc, char** argv)
{
  try
  {
    const double pi = 4.0*atan(1.0);
    double lambda = 1.25*pi*pi;

    int nx = 32;
    int nt = 10;
    double tFinal = 1.0/lambda;

    Sundance::setOption("nx", nx, "Number of elements");
    Sundance::setOption("nt", nt, "Number of timesteps");
    Sundance::setOption("tFinal", tFinal, "Final time");
    
    Sundance::init(&argc, &argv);

    /* Creation of vector type */
    VectorType<double> vecType = new EpetraVectorType();

    /* Set up mesh */
    MeshType meshType = new BasicSimplicialMeshType();
      
    MeshSource meshSrc = new PartitionedRectangleMesher(
      0.0, 1.0, nx,
      0.0, 1.0, nx,
      meshType);
    Mesh mesh = meshSrc.getMesh();

    /* 
     * Specification of cell filters
     */
    CellFilter interior = new MaximalCellFilter();
    CellFilter edges = new DimensionalCellFilter(1);
    CellFilter west = edges.coordSubset(0, 0.0);
    CellFilter east = edges.coordSubset(0, 1.0);
    CellFilter south = edges.coordSubset(1, 0.0);
    CellFilter north = edges.coordSubset(1, 1.0);

    /* set up test and unknown functions */
    BasisFamily basis = new Lagrange(1);
    Expr u = new UnknownFunction(basis, "u");
    Expr v = new TestFunction(basis, "v");

    /* set up differential operators */
    Expr grad = gradient(2);

    Expr x = new CoordExpr(0);
    Expr y = new CoordExpr(1);

    Expr t = new Sundance::Parameter(0.0);
    Expr tPrev = new Sundance::Parameter(0.0);


    DiscreteSpace discSpace(mesh, basis, vecType);
    Expr uExact = cos(0.5*pi*y)*sin(pi*x)*exp(-lambda*t);
    L2Projector proj(discSpace, uExact);
    Expr uPrev = proj.project();


    /* 
     * We need a quadrature rule for doing the integrations 
     */
    QuadratureFamily quad = new GaussianQuadrature(2);

    double deltaT = tFinal/nt;

    Expr gWest = -pi*exp(-lambda*t)*cos(0.5*pi*y);
    Expr gWestPrev = -pi*exp(-lambda*tPrev)*cos(0.5*pi*y);
    
    /* Create the weak form */
    Expr eqn = Integral(interior, v*(u-uPrev)/deltaT
      + 0.5*(grad*v)*(grad*u + grad*uPrev), quad)
      + Integral(west, -0.5*v*(gWest+gWestPrev), quad);

    Expr bc = EssentialBC(east + north, v*u, quad);

    
    LinearProblem prob(mesh, eqn, bc, v, u, vecType);

    
    LinearSolver<double> solver 
      = LinearSolverBuilder::createSolver("amesos.xml");

    FieldWriter w0 = new VTKWriter("TransientHeat2D-0");
    w0.addMesh(mesh);
    w0.addField("T", new ExprFieldWrapper(uPrev[0]));
    w0.write();

    for (int i=0; i<nt; i++)
    {
      t.setParameterValue((i+1)*deltaT);
      tPrev.setParameterValue(i*deltaT);
      Out::root() << "t=" << (i+1)*deltaT << endl;
      Expr uNext = prob.solve(solver);
      
      ostringstream oss;
      oss << "TransientHeat2D-" << i+1;
      FieldWriter w = new VTKWriter(oss.str());
      w.addMesh(mesh);
      w.addField("T", new ExprFieldWrapper(uNext[0]));
      w.write();

      updateDiscreteFunction(uNext, uPrev);
    }


    
    double err = L2Norm(mesh, interior, uExact-uPrev, quad);
    Out::root() << "error norm=" << err << endl;

    double h = 1.0/(nx-1.0);
    double tol = 0.1*(pow(h,2.0) + pow(lambda*deltaT, 2.0));
    Out::root() << "tol=" << tol << endl;
    
    
    Sundance::passFailTest(err, tol);
  }
	catch(std::exception& e) 
  {
    Sundance::handleException(e);
  }
  Sundance::finalize(); 
  return Sundance::testStatus();
}
示例#5
0
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(); 
}
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();
}
void LinearPDEConstrainedObj
::solveStateAndAdjoint(const Vector<double>& x) const
{
  Tabs tab(0);
  PLAYA_MSG2(verb(), tab << "solving state and adjoint"); 
  PLAYA_MSG3(verb(), tab << "|x|=" << x.norm2()); 
  PLAYA_MSG5(verb(), tab << "x=" << endl << tab << x.norm2()); 

  Tabs tab1;
  setDiscreteFunctionVector(designVarVal(), x);

  PLAYA_MSG3(verb(), tab1 << "solving state eqns");
  /* solve the state equations in order */
  for (int i=0; i<stateProbs_.size(); i++)
  {
    SolverState<double> status 
      = stateProbs_[i].solve(solvers_[i], stateVarVals(i));

    /* if the solve failed, write out the design var and known state
     * variables */
    if (status.finalState() != SolveConverged)
    {
      FieldWriter w = new VTKWriter("badSolve");
      w.addMesh(Lagrangian().mesh());
      w.addField("designVar", new ExprFieldWrapper(designVarVal()));
      for (int j=0; j<i; j++)
      {
        Expr tmp = stateVarVals(j).flatten();
        for (int k=0; k<tmp.size(); k++)
        {
          w.addField("stateVar-"+Teuchos::toString(j)+"-"+Teuchos::toString(k),
            new ExprFieldWrapper(tmp[k]));
        }
      }
      w.write();
    }
    TEUCHOS_TEST_FOR_EXCEPTION(status.finalState() != SolveConverged,
      std::runtime_error,
      "state equation " << i 
      << " could not be solved: status="
      << status.stateDescription());
  }

  PLAYA_MSG3(verb(), tab1 << "done solving state eqns");

  /* do postprocessing */
  statePostprocCallback();

  PLAYA_MSG3(verb(), tab1 << "solving adjoint eqns");

  /* solve the adjoint equations in reverse order */
  for (int i=adjointProbs_.size()-1; i>=0; i--)
  {
    SolverState<double> status 
      = adjointProbs_[i].solve(solvers_[i], adjointVarVals(i));

    /* if the solve failed, write out the design var and known state
     * and adjoint variables */
    if (status.finalState() != SolveConverged)
    {
      FieldWriter w = new VTKWriter("badSolve");
      w.addMesh(Lagrangian().mesh());
      w.addField("designVar", new ExprFieldWrapper(designVarVal()));
      for (int j=0; j<stateProbs_.size(); j++)
      {
        Expr tmp = stateVarVals(j).flatten();
        for (int k=0; k<tmp.size(); k++)
        {
          w.addField("stateVar-"+Teuchos::toString(j)+"-"+Teuchos::toString(k),
            new ExprFieldWrapper(tmp[k]));
        }
      }
      for (int j=adjointProbs_.size()-1; j>i; j--)
      {
        Expr tmp = adjointVarVals(j).flatten();
        for (int k=0; k<tmp.size(); k++)
        {
          w.addField("adjointVar-"+Teuchos::toString(j)+"-"+Teuchos::toString(k),
            new ExprFieldWrapper(tmp[k]));
        }

      }
      w.write();

    }
    TEUCHOS_TEST_FOR_EXCEPTION(status.finalState() != SolveConverged,
      std::runtime_error,
      "adjoint equation " << i 
      << " could not be solved: status="
      << status.stateDescription());
  }
  PLAYA_MSG3(verb(), tab1 << "done solving adjoint eqns");
  PLAYA_MSG2(verb(), tab1 << "done solving state and adjoint eqns");
}
bool BlockStochPoissonTest1D()
{
  /* We will do our linear algebra using Epetra */
  VectorType<double> vecType = new EpetraVectorType();

  /* Read a mesh */
  MeshType meshType = new BasicSimplicialMeshType();
  int nx = 32;
  MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx, 
    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 pts = new DimensionalCellFilter(0);
  CellFilter left = pts.subset(new CoordinateValueCellPredicate(0,0.0));
  CellFilter right = pts.subset(new CoordinateValueCellPredicate(0,1.0));

  Expr x = new CoordExpr(0);

  /* Create the stochastic coefficients */
  int nDim = 1;
  int order = 6;
#ifdef HAVE_SUNDANCE_STOKHOS
  Out::root() << "using Stokhos hermite basis" << std::endl;
  SpectralBasis pcBasis = new Stokhos::HermiteBasis<int,double>(order);
#else
  Out::root() << "using George's hermite basis" << std::endl;
  SpectralBasis pcBasis = new HermiteSpectralBasis(nDim, order);
#endif
    
  Array<Expr> q(pcBasis.nterms());
  Array<Expr> kappa(pcBasis.nterms());
  Array<Expr> uEx(pcBasis.nterms());

  double a = 0.1;

  q[0] = -2 + pow(a,2)*(4 - 9*x)*x - 2*pow(a,3)*(-1 + x)*(1 + 3*x*(-3 + 4*x));
  q[1] = -(a*(-3 + 10*x + 2*a*(-1 + x*(8 - 9*x +
          a*(-4 + 3*(5 - 4*x)*x + 12*a*(-1 + x)*(1 + 5*(-1 + x)*x))))));
  q[2] = a*(-4 + 6*x + a*(1 - x*(2 + 3*x) + a*(4 - 28*x + 30*pow(x,2))));
  q[3] = -(pow(a,2)*(-3 + x*(20 - 21*x +
        a*(-4 + 3*(5 - 4*x)*x + 24*a*(-1 + x)*(1 + 5*(-1 + x)*x)))));
  q[4] = pow(a,3)*(1 + x*(-6 + x*(3 + 4*x)));
  q[5] = -4*pow(a,4)*(-1 + x)*x*(1 + 5*(-1 + x)*x);
  q[6] = 0.0;

  uEx[0] = -((-1 + x)*x);
  uEx[1] = -(a*(-1 + x)*pow(x,2));
  uEx[2] = a*pow(-1 + x,2)*x;
  uEx[3] = pow(a,2)*pow(-1 + x,2)*pow(x,2);
  uEx[4] = 0.0;
  uEx[5] = 0.0;
  uEx[6] = 0.0;

  kappa[0] = 1.0;
  kappa[1] = a*x;
  kappa[2] = -(pow(a,2)*(-1 + x)*x);

  kappa[3] = 1.0; // unused
  kappa[4] = 1.0; // unused
  kappa[5] = 1.0; // unused
  kappa[6] = 1.0; // unused


  Array<Expr> uBC(pcBasis.nterms());
  for (int i=0; i<pcBasis.nterms(); i++) uBC[i] = 0.0;

  int L = nDim+2;
  int P = pcBasis.nterms();
  Out::os() << "L = " << L << std::endl;
  Out::os() << "P = " << P << std::endl;
    
  /* Create the unknown and test functions. Do NOT use the spectral
   * basis here */
  Expr u = new UnknownFunction(new Lagrange(4), "u");
  Expr v = new TestFunction(new Lagrange(4), "v");

  /* Create differential operator and coordinate function */
  Expr dx = new Derivative(0);
  Expr grad = dx;


  /* We need a quadrature rule for doing the integrations */
  QuadratureFamily quad = new GaussianQuadrature(12);

  /* Now we create problem objects to build each $K_j$ and $f_j$.
   * There will be L matrix-vector pairs */
  Array<Expr> eqn(P);
  Array<Expr> bc(P);
  Array<LinearProblem> prob(P);
  Array<LinearOperator<double> > KBlock(L);
  Array<Vector<double> > fBlock(P);
  Array<Vector<double> > solnBlock;

  for (int j=0; j<P; j++)
  {
    eqn[j] = Integral(interior, kappa[j]*(grad*v)*(grad*u) + v*q[j], quad);
    bc[j] = EssentialBC(left+right, v*(u-uBC[j]), quad);
    prob[j] = LinearProblem(mesh, eqn[j], bc[j], v, u, vecType); 
    if (j<L) KBlock[j] = prob[j].getOperator();
    fBlock[j] = -1.0*prob[j].getSingleRHS();
  }

  /* Read the solver to be used on the diagonal blocks */
  LinearSolver<double> diagSolver 
    = LinearSolverBuilder::createSolver("amesos.xml");

    
  double convTol = 1.0e-12;
  int maxIters = 30;
  int verb = 1;
  StochBlockJacobiSolver solver(diagSolver, pcBasis,
    convTol, maxIters, verb);
    
  solver.solve(KBlock, fBlock, solnBlock);

  /* write the solution */
  FieldWriter w = new MatlabWriter("Stoch1D");
  w.addMesh(mesh);
  DiscreteSpace discSpace(mesh, new Lagrange(4), vecType);
  for (int i=0; i<P; i++)
  {
    L2Projector proj(discSpace, uEx[i]);
    Expr ue_i = proj.project();
    Expr df = new DiscreteFunction(discSpace, solnBlock[i]);
    w.addField("u["+ Teuchos::toString(i)+"]", 
      new ExprFieldWrapper(df));
    w.addField("uEx["+ Teuchos::toString(i)+"]", 
      new ExprFieldWrapper(ue_i));
  }
  w.write();

  double totalErr2 = 0.0;
  DiscreteSpace discSpace4(mesh, new Lagrange(4), vecType);
  for (int i=0; i<P; i++)
  {
    Expr df = new DiscreteFunction(discSpace4, solnBlock[i]);
    Expr errExpr = Integral(interior, pow(uEx[i]-df, 2.0), quad);
    Expr scaleExpr = Integral(interior, pow(uEx[i], 2.0), quad);
    double errSq = evaluateIntegral(mesh, errExpr);
    double scale = evaluateIntegral(mesh, scaleExpr);
    if (scale > 0.0) 
      Out::os() << "mode i=" << i << " error=" << sqrt(errSq/scale) << std::endl;
    else
      Out::os() << "mode i=" << i << " error=" << sqrt(errSq) << std::endl;
  }
    
  double tol = 1.0e-12;
    
  return SundanceGlobal::checkTest(sqrt(totalErr2), tol);
}
bool DuffingFloquet()
{
  int np = MPIComm::world().getNProc();
  TEUCHOS_TEST_FOR_EXCEPT(np != 1);

  const double pi = 4.0*atan(1.0);

  /* We will do our linear algebra using Epetra */
  VectorType<double> vecType = new EpetraVectorType();

  /* Create a periodic mesh */
  int nx = 128;

  MeshType meshType = new PeriodicMeshType1D();
  MeshSource mesher = new PeriodicLineMesher(0.0, 2.0*pi, nx, 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 pts = new DimensionalCellFilter(0);
      
  CellFilter left = pts.subset(new CoordinateValueCellPredicate(0,0.0));
  CellFilter right = pts.subset(new CoordinateValueCellPredicate(0,2.0*pi));
      
  /* Create unknown and test functions, discretized using first-order
   * Lagrange interpolants */
  Expr u1 = new UnknownFunction(new Lagrange(1), "u1");
  Expr u2 = new UnknownFunction(new Lagrange(1), "u2");
  Expr v1 = new TestFunction(new Lagrange(1), "v1");
  Expr v2 = new TestFunction(new Lagrange(1), "v2");

  /* Create differential operator and coordinate function */
  Expr dx = new Derivative(0);
  Expr x = new CoordExpr(0);

  /* We need a quadrature rule for doing the integrations */
  QuadratureFamily quad = new GaussianQuadrature(4);

  double F0 = 0.5;
  double gamma = 2.0/3.0;
  double a0 = 1.0;
  double w0 = 1.0;
  double eps = 0.5;

  Expr u1Guess = -0.75*cos(x) + 0.237*sin(x);
  Expr u2Guess = 0.237*cos(x) + 0.75*sin(x);

  DiscreteSpace discSpace(mesh, 
    List(new Lagrange(1), new Lagrange(1)),
    vecType);
  L2Projector proj(discSpace, List(u1Guess, u2Guess));
  Expr u0 = proj.project();


  Expr rhs1 = u2;
  Expr rhs2 = -w0*w0*u1 - gamma*u2 - eps*w0*w0*pow(u1,3.0)/a0/a0 
    + F0*w0*w0*sin(x);

  /* Define the weak form */
  Expr eqn = Integral(interior, 
    v1*(dx*u1 - rhs1) + v2*(dx*u2 - rhs2),
    quad);
  Expr dummyBC ; 

  NonlinearProblem prob(mesh, eqn, dummyBC, List(v1,v2), List(u1,u2), 
    u0, vecType);


  ParameterXMLFileReader reader("nox.xml");
  ParameterList solverParams = reader.getParameters();

  Out::root() << "finding periodic solution" << endl;
  NOXSolver solver(solverParams);
  prob.solve(solver);

  /* unfold the solution onto a non-periodic mesh */
      
  Expr uP = unfoldPeriodicDiscreteFunction(u0, "u_p");
  Out::root() << "uP=" << uP << endl;
      
  Mesh unfoldedMesh = DiscreteFunction::discFunc(uP)->mesh();
  DiscreteSpace unfDiscSpace = DiscreteFunction::discFunc(uP)->discreteSpace();

  FieldWriter writer = new MatlabWriter("Floquet.dat");
  writer.addMesh(unfoldedMesh);
  writer.addField("u_p[0]", new ExprFieldWrapper(uP[0]));
  writer.addField("u_p[1]", new ExprFieldWrapper(uP[1]));

  Array<Expr> a(2);
  a[0] = new Sundance::Parameter(0.0, "a1");
  a[1] = new Sundance::Parameter(0.0, "a2");


  Expr bc = EssentialBC(left, v1*(u1-uP[0]-a[0]) + v2*(u2-uP[1]-a[1]), quad);

  NonlinearProblem unfProb(unfoldedMesh, eqn, bc, 
    List(v1,v2), List(u1,u2), uP, vecType);

  unfProb.setEvalPoint(uP);

  LinearOperator<double> J = unfProb.allocateJacobian();
  Vector<double> b = J.domain().createMember();

  LinearSolver<double> linSolver
    = LinearSolverBuilder::createSolver("amesos.xml");
        
  SerialDenseMatrix<int, double> F(a.size(), a.size());

  for (int i=0; i<a.size(); i++)
  {
    Out::root() << "doing perturbed orbit #" << i << endl;
    for (int j=0; j<a.size(); j++) 
    {
      if (i==j) a[j].setParameterValue(1.0);
      else a[j].setParameterValue(0.0);
    }
        
    unfProb.computeJacobianAndFunction(J, b);
    Vector<double> w = b.copy();
    linSolver.solve(J, b, w);
    Expr w_i = new DiscreteFunction(unfDiscSpace, w);

    for (int j=0; j<a.size(); j++)
    {
      Out::root() << "postprocessing" << i << endl;

      writer.addField("w[" + Teuchos::toString(i)
        + ", " + Teuchos::toString(j) + "]", new ExprFieldWrapper(w_i[j]));
      Expr g = Integral(right, w_i[j], quad);
      F(j,i) = evaluateIntegral(unfoldedMesh, g);
    }
  }

  writer.write();

  Out::root() << "Floquet matrix = " << endl
              << F << endl;
        

  Out::root() << "doing eigenvalue analysis" << endl;
  Array<double> ew_r(a.size());
  Array<double> ew_i(a.size());
  int lWork = 6*a.size();
  Array<double> work(lWork);
  int info = 0;
  LAPACK<int, double> lapack;
  lapack.GEEV('N','N', a.size(), F.values(),
    a.size(), &(ew_r[0]), &(ew_i[0]), 0, 1, 0, 1, &(work[0]), lWork,
    &info);

  TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
    std::runtime_error,
    "LAPACK GEEV returned error code =" << info);
      
  Array<double> ew(a.size());
  for (int i=0; i<a.size(); i++)
  {
    ew[i] = sqrt(ew_r[i]*ew_r[i]+ew_i[i]*ew_i[i]);
    Out::root() << setw(5) << i 
                << setw(16) << ew_r[i] 
                << setw(16) << ew_i[i] 
                << setw(16) << ew[i]
                << endl;
  }

  double err = ::fabs(ew[0] - 0.123);
  return SundanceGlobal::checkTest(err, 0.001);
}
示例#10
0
int main( int argc , char **argv )
{
    try {
        int nx = 128;
        double C = 4.0;
        std::string solverFile = "aztec-ml.xml";
        Sundance::setOption("nx", nx, "number of elements in x");
        Sundance::setOption("C", C, "Nitsche penalty");
        Sundance::setOption("solver", solverFile, "name of XML file for solver");

        Sundance::init( &argc , &argv );
        int np = MPIComm::world().getNProc();
        int npx = -1;
        int npy = -1;
        balanceXY(np, &npx, &npy);
        TEST_FOR_EXCEPT(npx < 1);
        TEST_FOR_EXCEPT(npy < 1);
        TEST_FOR_EXCEPT(npx * npy != np);

        VectorType<double> vecType = new EpetraVectorType();

        const int k = 1;
        const int splitBC = 1;

        MeshType meshType = new BasicSimplicialMeshType();
        MeshSource mesher = new PartitionedRectangleMesher( 0.0 , 1.0 , nx , npx ,
                0.0 , 1.0 , nx , npy,
                meshType );
        Mesh mesh = mesher.getMesh();

        BasisFamily L = new Lagrange( k );

        Expr u = new UnknownFunction( L , "u" );
        Expr v = new TestFunction( L , "v" );
        QuadratureFamily quad = new GaussianQuadrature( 2 * k );

        Expr h = new CellDiameterExpr();
        Expr alpha = C / h;
        Expr eqn = poissonEquationNitsche( splitBC, u , v , alpha , quad );
        Expr bc;


        LinearProblem prob( mesh , eqn , bc , v , u , vecType);

#ifdef HAVE_CONFIG_H
        ParameterXMLFileReader reader(searchForFile("SolverParameters/" + solverFile));
#else
        ParameterXMLFileReader reader(solverFile);
#endif
        ParameterList solverParams = reader.getParameters();
        LinearSolver<double> solver
            = LinearSolverBuilder::createSolver(solverParams);


        Expr soln = prob.solve( solver );


        FieldWriter w = new VTKWriter( "NitschePoisson2D" );
        w.addMesh( mesh );
        w.addField( "u" , new ExprFieldWrapper( soln ) );
        w.write();

        Expr x = new CoordExpr(0);
        Expr y = new CoordExpr(1);
        QuadratureFamily quad4 = new GaussianQuadrature(4);

        CellFilter interior = new MaximalCellFilter();
        const double pi = 4.0*atan(1.0);
        Expr exactSoln = sin(pi*x)*sin(pi*y);
        Expr err = exactSoln - soln;
        Expr errExpr = Integral(interior,
                                err*err,
                                quad4);
        FunctionalEvaluator errInt(mesh, errExpr);

        double errorSq = errInt.evaluate();
        cout << "error norm = " << sqrt(errorSq) << std::endl << std::endl;


        Sundance::passFailTest(sqrt(errorSq), 1.0e-4);
    }
    catch (std::exception &e)
    {
        Sundance::handleException(e);
    }
    Sundance::finalize();
    return Sundance::testStatus();
}
int main(int argc, char** argv)
{
  try
  {
    int nx = 32;
    double convTol = 1.0e-8;
    double lambda = 0.5;
    Sundance::setOption("nx", nx, "Number of elements");
    Sundance::setOption("tol", convTol, "Convergence tolerance");
    Sundance::setOption("lambda", lambda, "Lambda (parameter in Bratu's equation)");

    Sundance::init(&argc, &argv);

    Out::root() << "Bratu problem (lambda=" << lambda << ")" << endl;
    Out::root() << "Fixed-point iteration" << endl << endl;

    VectorType<double> vecType = new EpetraVectorType();

    MeshType meshType = new BasicSimplicialMeshType();
    MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx, meshType);
    Mesh mesh = mesher.getMesh();

    CellFilter interior = new MaximalCellFilter();
    CellFilter sides = new DimensionalCellFilter(mesh.spatialDim()-1);
    CellFilter left = sides.subset(new CoordinateValueCellPredicate(0, 0.0));
    CellFilter right = sides.subset(new CoordinateValueCellPredicate(0, 1.0));
    
    BasisFamily basis = new Lagrange(1);
    Expr u = new UnknownFunction(basis, "u");
    Expr v = new TestFunction(basis, "v");

    Expr grad = gradient(1);

    Expr x = new CoordExpr(0);



    const double pi = 4.0*atan(1.0);
    Expr uExact = sin(pi*x);
    Expr R = pi*pi*uExact - lambda*exp(uExact);

    QuadratureFamily quad4 = new GaussianQuadrature(4);
    QuadratureFamily quad2 = new GaussianQuadrature(2);

    DiscreteSpace discSpace(mesh, basis, vecType);
    Expr uPrev = new DiscreteFunction(discSpace, 0.5);
    Expr uCur = copyDiscreteFunction(uPrev);

    Expr eqn 
      = Integral(interior, (grad*u)*(grad*v) - v*lambda*exp(uPrev) - v*R, quad4);

    Expr h = new CellDiameterExpr();
    Expr bc = EssentialBC(left+right, v*u/h, quad4); 

    LinearProblem prob(mesh, eqn, bc, v, u, vecType);

    Expr normSqExpr = Integral(interior, pow(u-uPrev, 2.0), quad2);
    Functional normSqFunc(mesh, normSqExpr, vecType);
    FunctionalEvaluator normSqEval = normSqFunc.evaluator(u, uCur);

    LinearSolver<double> linSolver 
      = LinearSolverBuilder::createSolver("amesos.xml");

    Out::root() << "Fixed-point iteration" << endl;
    int maxIters = 20;
    Expr soln ;
    bool converged = false;

    for (int i=0; i<maxIters; i++)
    {
      /* solve for the next u */
      prob.solve(linSolver, uCur);
      /* evaluate the norm of (uCur-uPrev) using 
       * the FunctionalEvaluator defined above */
      double deltaU = sqrt(normSqEval.evaluate());
      Out::root() << "Iter=" << setw(3) << i << " ||Delta u||=" << setw(20)
                  << deltaU << endl; 
      /* check for convergence */  
      if (deltaU < convTol) 
      {
        soln = uCur;
        converged = true;
        break;
      }
      /* get the vector from the current discrete function */
      Vector<double> uVec = getDiscreteFunctionVector(uCur);
      /* copy the vector into the previous discrete function */ 
      setDiscreteFunctionVector(uPrev, uVec);
    } 
    TEUCHOS_TEST_FOR_EXCEPTION(!converged, std::runtime_error, 
      "Fixed point iteration did not converge after " 
      << maxIters << " iterations");
    
    FieldWriter writer = new DSVWriter("FixedPointBratu.dat");
    writer.addMesh(mesh);
    writer.addField("soln", new ExprFieldWrapper(soln[0]));
    writer.write();

    Out::root() << "Converged!" << endl << endl;

    double L2Err = L2Norm(mesh, interior, soln-uExact, quad4);
    Out::root() << "L2 Norm of error: " << L2Err << endl;
    
    Sundance::passFailTest(L2Err, 1.5/((double) nx*nx));
  }
	catch(exception& e) 
  {
    Sundance::handleException(e);
  }
  Sundance::finalize(); 
}
int main(int argc, char** argv)
{
  try
  {
    int nx = 32;
    double convTol = 1.0e-8;
    double lambda = 0.5;
    Sundance::setOption("nx", nx, "Number of elements");
    Sundance::setOption("tol", convTol, "Convergence tolerance");
    Sundance::setOption("lambda", lambda, "Lambda (parameter in Bratu's equation)");

    Sundance::init(&argc, &argv);

    Out::root() << "Bratu problem (lambda=" << lambda << ")" << endl;
    Out::root() << "Newton's method with automated linearization" 
                << endl << endl;

    VectorType<double> vecType = new EpetraVectorType();

    MeshType meshType = new BasicSimplicialMeshType();
    MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx, meshType);
    Mesh mesh = mesher.getMesh();

    CellFilter interior = new MaximalCellFilter();
    CellFilter sides = new DimensionalCellFilter(mesh.spatialDim()-1);
    CellFilter left = sides.subset(new CoordinateValueCellPredicate(0, 0.0));
    CellFilter right = sides.subset(new CoordinateValueCellPredicate(0, 1.0));
    
    BasisFamily basis = new Lagrange(1);
    Expr u = new UnknownFunction(basis, "w");
    Expr v = new TestFunction(basis, "v");

    Expr grad = gradient(1);

    Expr x = new CoordExpr(0);

    const double pi = 4.0*atan(1.0);
    Expr uExact = sin(pi*x);
    Expr R = pi*pi*uExact - lambda*exp(uExact);

    QuadratureFamily quad4 = new GaussianQuadrature(4);
    QuadratureFamily quad2 = new GaussianQuadrature(2);

    DiscreteSpace discSpace(mesh, basis, vecType);
    Expr uPrev = new DiscreteFunction(discSpace, 0.5);

    Expr eqn 
      = Integral(interior, (grad*v)*(grad*u) - v*lambda*exp(u) - v*R, quad4);

    Expr h = new CellDiameterExpr();
    Expr bc = EssentialBC(left+right, v*u/h, quad2); 

    NonlinearProblem prob(mesh, eqn, bc, v, u, uPrev, vecType);

    NonlinearSolver<double> solver 
      = NonlinearSolverBuilder::createSolver("playa-newton-amesos.xml");

    Out::root() << "Newton solve" << endl;

    SolverState<double> state = prob.solve(solver);
    
    TEUCHOS_TEST_FOR_EXCEPTION(state.finalState() != SolveConverged,
      std::runtime_error,
      "Nonlinear solve failed to converge: message=" << state.finalMsg());
    
    Expr soln = uPrev;
    FieldWriter writer = new DSVWriter("AutoLinearizedBratu.dat");
    writer.addMesh(mesh);
    writer.addField("soln", new ExprFieldWrapper(soln[0]));
    writer.write();

    Out::root() << "Converged!" << endl << endl;

    double L2Err = L2Norm(mesh, interior, soln-uExact, quad4);
    Out::root() << "L2 Norm of error: " << L2Err << endl;
    
    Sundance::passFailTest(L2Err, 1.5/((double) nx*nx));
  }
	catch(std::exception& e) 
  {
    Sundance::handleException(e);
  }
  Sundance::finalize(); 
  return Sundance::testStatus();
}
bool AToCDensitySample()
{

  /* We will do our linear algebra using Epetra */
  VectorType<double> vecType = new EpetraVectorType();

  /* Create a mesh. It will be of type BasisSimplicialMesh, and will
   * be built using a PartitionedLineMesher. */
  MeshType meshType = new BasicSimplicialMeshType();
  MeshSource mesher = new PartitionedRectangleMesher(-1.0, 1.0, 32, 1,
    -1.0, 1.0, 32, 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();

  Expr x = new CoordExpr(0);
  Expr y = new CoordExpr(1);

  BasisFamily L1 = new Lagrange(1);
  DiscreteSpace discSpace(mesh, List(L1, L1), vecType);
      
  /* Discretize some expression for the force. We'll pick a linear function
   * so that it can be interpolated exactly, letting us check the 
   * validity of our interpolations. */
  L2Projector proj(discSpace, List(x, y));
  Expr F = proj.project();

      
  /* create a sampler */
  cout << "making grid" << std::endl;
  AToCPointLocator locator(mesh, interior, createVector(tuple(200, 200)));
      
  AToCDensitySampler sampler(locator, vecType);

  CToAInterpolator forceInterpolator(locator, F);

  cout << "making points" << std::endl;
  /* create a bunch of particles */
  int nCells = mesh.numCells(2);
  int nPts = 15000;

  Array<double> pos(2*nPts);
  Array<double> f(F.size() * nPts);
  Array<Point> physPts;

  /* We'll generate random sample points in a way that lets us make an exact check
   * of the density recovery. We pick random cells, then random local coordinates
   * within each cell. This way, we can compute the density exactly as we
   * go, giving us something to check the recovered density against. */
  Array<int> counts(nCells);
  for (int i=0; i<nPts; i++)
  {
    /* pick a random cell */
    int cell = (int) floor(nCells * drand48());
    counts[cell]++;
    /* generate a point in local coordinates */
    double s = drand48();
    double t = drand48() * (1.0-s);
    Point refPt(s, t);
    /* map to physical coordinates */
    mesh.pushForward(2, tuple(cell), tuple(refPt), physPts);
    Point X = physPts[0];
    pos[2*i] = X[0];
    pos[2*i+1] = X[1];
  }

  cout << "sampling..." << std::endl;
  Expr density = sampler.sample(createVector(pos), 1.0);

  cout << "computing forces..." << std::endl;
  forceInterpolator.interpolate(pos, f);

  double maxForceErr = 0.0;
  for (int i=0; i<nPts; i++)
  {
    double x0 = pos[2*i];
    double y0 = pos[2*i+1];
    double fx = x0;
    double fy = y0;
    double df = ::fabs(fx - f[2*i]) + ::fabs(fy - f[2*i+1]);
    maxForceErr = max(maxForceErr, df);
  }
  cout << "max force error = " << maxForceErr << std::endl;

  cout << "writing..." << std::endl;

  /* Write the field in VTK format */
  FieldWriter w = new VTKWriter("Density2d");
  w.addMesh(mesh);
  w.addField("rho", new ExprFieldWrapper(density));
  w.write();

  double errorSq = 0.0;

  double tol = 1.0e-6;
  return SundanceGlobal::passFailTest(::sqrt(errorSq), tol);
}
示例#14
0
bool PoissonOnDisk()
{
#ifdef HAVE_SUNDANCE_EXODUS

  /* We will do our linear algebra using Epetra */
  VectorType<double> vecType = new EpetraVectorType();

  /* Get a mesh */
  MeshType meshType = new BasicSimplicialMeshType();
  MeshSource meshReader = new ExodusNetCDFMeshReader("disk.ncdf", meshType);
  Mesh mesh = meshReader.getMesh();

  /* Create a cell filter that will identify the maximal cells
   * in the interior of the domain */
  CellFilter interior = new MaximalCellFilter();
  CellFilter bdry = new BoundaryCellFilter();


      
  /* Create unknown and test functions, discretized using first-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 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);

  /* Define the weak form */
  Expr eqn = Integral(interior, (grad*v)*(grad*u)  + v, quad2);
  /* Define the Dirichlet BC */
  Expr bc = EssentialBC(bdry, v*u, quad4);


  /* We can now set up the linear problem! */
  LinearProblem prob(mesh, eqn, bc, v, u, vecType);

  LinearSolver<double> solver 
    = LinearSolverBuilder::createSolver("amesos.xml");

  Expr soln = prob.solve(solver);

  double R = 1.0;
  Expr exactSoln = 0.25*(x*x + y*y - R*R);

  DiscreteSpace discSpace(mesh, new Lagrange(1), vecType);
  Expr du = L2Projector(discSpace, exactSoln-soln).project();

  /* Write the field in VTK format */
  FieldWriter w = new VTKWriter("PoissonOnDisk");
  w.addMesh(mesh);
  w.addField("soln", new ExprFieldWrapper(soln[0]));
  w.addField("error", new ExprFieldWrapper(du));
  w.write();

      
  Expr errExpr = Integral(interior, 
    pow(soln-exactSoln, 2),
    new GaussianQuadrature(4));

  double errorSq = evaluateIntegral(mesh, errExpr);
  std::cerr << "soln error norm = " << sqrt(errorSq) << std::endl << std::endl;


  /* Check error in automatically-computed cell normals */
  /* Create a cell normal expression. Note that this is NOT a constructor
   * call, hence no "new" before the CellNormalExpr() function. The
   * argument "2" is the spatial dimension (mandatory), and 
   * the "n" is the name of the expression (optional). 
   */
  Expr n = CellNormalExpr(2, "n");
  Expr nExact = List(x, y)/sqrt(x*x + y*y);
  Expr nErrExpr = Integral(bdry, pow(n-nExact, 2.0), new GaussianQuadrature(1));
  double nErrorSq = evaluateIntegral(mesh, nErrExpr);
  Out::root() << "normalVector error norm = " 
              << sqrt(nErrorSq) << std::endl << std::endl;

  double tol = 1.0e-4;
  return SundanceGlobal::checkTest(sqrt(errorSq + nErrorSq), tol);
#else
  std::cout << "dummy PoissonOnDisk PASSED. Enable Exodus to run the actual test" << std::endl;
  return true;
#endif
}
示例#15
0
int main(int argc, char** argv)
{
  
  try
		{
      Sundance::init(&argc, &argv);
            
      /* We will do our linear algebra using Epetra */
      VectorType<double> vecType = new EpetraVectorType();

      /* Create a mesh. It will be of type BasisSimplicialMesh, and will
       * be built using a PartitionedLineMesher. */
      MeshType meshType = new BasicSimplicialMeshType();
      int nx = 32;

      MeshSource mesher = new PartitionedRectangleMesher(
        0.0, 1.0, nx,
        0.0, 1.0, nx,
        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();

      /* Make cell filters for the east and west boundaries */
      CellFilter edges = new DimensionalCellFilter(1);
      CellFilter west = edges.coordSubset(0, 0.0);
      CellFilter east = edges.coordSubset(0, 1.0);

      /* Create unknown and test functions */
      Expr u = new UnknownFunction(new Lagrange(1), "u");
      Expr v = new TestFunction(new Lagrange(1), "v");

      /* Create differential operator and coordinate function */
      Expr x = new CoordExpr(0);
      Expr grad = gradient(1);

      /* We need a quadrature rule for doing the integrations */
      QuadratureFamily quad = new GaussianQuadrature(4);

      /* Define the parameter */
      Expr xi = new Sundance::Parameter(0.0);

      /* Construct a forcing term to provide an exact solution for
       * validation purposes. This will involve the parameter. */
      Expr uEx = x*(1.0-x)*(1.0+xi*exp(x));
      Expr f = -(-20 - exp(x)*xi*(1 + 32*x + 10*x*x + 
          exp(x)*(-1 + 2*x*(2 + x))*xi))/10.0;

      /* Define the weak form, using the parameter expression. This weak form
       * can be used for all parameter values. */
      Expr eqn = Integral(interior, 
        (1.0 + 0.1*xi*exp(x))*(grad*v)*(grad*u) - f*v, quad);

      /* Define the Dirichlet BC */
      Expr h = new CellDiameterExpr();
      Expr bc = EssentialBC(east + west, v*u/h, quad);

      /* We can now set up the linear problem. This can be reused
       * for different parameter values. */
      LinearProblem prob(mesh, eqn, bc, v, u, vecType);

      /* make a projector for the exact solution. Just like the
       * problem, this can be reused for different parameter values. */
      DiscreteSpace ds(mesh, new Lagrange(1), vecType);
      L2Projector proj(ds, uEx);

      /* Get the solver and declare variables for the results */
      LinearSolver<double> solver = LinearSolverBuilder::createSolver("aztec-ml.xml");
      Expr soln;
      SolverState<double> state;

      /* Set up the sweep from xi=0 to xi=xiMax in nSteps steps. */
      int nSteps = 10;
      double xiMax = 2.0;
      
      /* Make an array in which to keep the observed errors */
      Array<double> err(nSteps);

      /* Do the sweep */
      for (int n=0; n<nSteps; n++)
      {
        /* Update the parameter value */
        double xiVal = xiMax*n/(nSteps - 1.0);
        xi.setParameterValue(xiVal);
        Out::root() << "step n=" << n << " of " << nSteps << " xi=" << xiVal;

        /* Solve the problem. The updated parameter value is automatically used. */
        state = prob.solve(solver, soln);

        TEUCHOS_TEST_FOR_EXCEPTION(state.finalState() != SolveConverged,
          std::runtime_error,
          "solve failed!");

        /* Project the exact solution onto a discrrete space for viz. The updated
         * parameter value is automatically used. */
        Expr uEx0 = proj.project();

        /* Write the approximate and exact solutions for viz */
        FieldWriter w = new VTKWriter("ParameterSweep-" + Teuchos::toString(n));
        w.addMesh(mesh);
        w.addField("u", new ExprFieldWrapper(soln[0]));
        w.addField("uEx", new ExprFieldWrapper(uEx0[0]));
        w.write();

        /* Compute the L2 norm of the error */
        err[n] = L2Norm(mesh, interior, soln-uEx, quad);
        Out::root() << " L2 error = " << err[n] << endl;
      } 

      /* The errors are O(h^2), so use that to set a tolerance */
      double hVal = 1.0/(nx-1.0);
      double fudge = 2.0;
      double tol = fudge*hVal*hVal;

      /* Find the max error over all parameter values */
      double maxErr = *std::max_element(err.begin(), err.end());

      /* Check the error */
      Sundance::passFailTest(maxErr, tol);
    }
	catch(std::exception& e)
		{
      Sundance::handleException(e);
		}
  Sundance::finalize(); 
  return Sundance::testStatus(); 
}
示例#16
0
int main(int argc, char** argv)
{
  try
		{
			Sundance::init(&argc, &argv);
      int np = MPIComm::world().getNProc();
      
      int nx = 48;
      int ny = 48;
      int npx = -1;
      int npy = -1;
      PartitionedRectangleMesher::balanceXY(np, &npx, &npy);
      TEUCHOS_TEST_FOR_EXCEPT(npx < 1);
      TEUCHOS_TEST_FOR_EXCEPT(npy < 1);
      TEUCHOS_TEST_FOR_EXCEPT(npx * npy != np);
      MeshType meshType = new BasicSimplicialMeshType();
      MeshSource mesher = new PartitionedRectangleMesher(0.0, 1.0, nx, npx, 
        0.0,  1.0, ny, npy, meshType);

      Mesh mesh = mesher.getMesh();
      CellFilter interior = new MaximalCellFilter();
      CellFilter bdry = new BoundaryCellFilter();
      
      /* Create a vector space factory, used to 
       * specify the low-level linear algebra representation */
      VectorType<double> vecType = new EpetraVectorType();
  
      /* create a discrete space on the mesh */
      DiscreteSpace discreteSpace(mesh, new Lagrange(1), vecType);

      /* initialize the design, state, and multiplier vectors */
      Expr alpha0 = new DiscreteFunction(discreteSpace, 1.0, "alpha0");
      Expr u0 = new DiscreteFunction(discreteSpace, 1.0, "u0");
      Expr lambda0 = new DiscreteFunction(discreteSpace, 1.0, "lambda0");

      /* create symbolic objects for test and unknown functions */
      Expr u = new UnknownFunction(new Lagrange(1), "u");
      Expr lambda = new UnknownFunction(new Lagrange(1), "lambda");
      Expr alpha = new UnknownFunction(new Lagrange(1), "alpha");

      /* create symbolic differential operators */
      Expr dx = new Derivative(0);
      Expr dy = new Derivative(1);
      Expr grad = List(dx, dy);

      /* create symbolic coordinate functions */
      Expr x = new CoordExpr(0);
      Expr y = new CoordExpr(1);

      /* create target function */
      const double pi = 4.0*atan(1.0);
      Expr uStar = sin(pi*x)*sin(pi*y);
      
      /* create quadrature rules of different orders */
      QuadratureFamily q1 = new GaussianQuadrature(1);
      QuadratureFamily q2 = new GaussianQuadrature(2);
      QuadratureFamily q4 = new GaussianQuadrature(4);

      /* Regularization weight */
      double R = 0.001;
      double U0 = 1.0/(1.0 + 4.0*pow(pi,4.0)*R);
      double A0 = -2.0*pi*pi*U0;

      /* Form objective function */
      Expr reg = Integral(interior, 0.5 * R * alpha*alpha, q2);
      Expr fit = Integral(interior, 0.5 * pow(u-uStar, 2.0), q4);

      Expr constraintEqn = Integral(interior, 
        (grad*lambda)*(grad*u) + lambda*alpha, q2);
      Expr L = reg + fit + constraintEqn;

      Expr constraintBC = EssentialBC(bdry, lambda*u, q2);
      Functional Lagrangian(mesh, L, constraintBC, vecType);
      
      LinearSolver<double> solver 
        = LinearSolverBuilder::createSolver("amesos.xml");

      RCP<ObjectiveBase> obj = rcp(new LinearPDEConstrainedObj(
        Lagrangian, u, u0, lambda, lambda0, alpha, alpha0,
        solver));

      Vector<double> xInit = obj->getInit();

      bool doFDCheck = false;
      if (doFDCheck)
      {
        Out::root() << "Doing FD check of gradient..." << endl;
        bool fdOK = obj->fdCheck(xInit, 1.0e-6, 2);
        if (fdOK) 
        {
          Out::root() << "FD check OK" << endl;
        }
        else
        {
          Out::root() << "FD check FAILED" << endl;
        }
      }

      RCP<UnconstrainedOptimizerBase> opt 
          = OptBuilder::createOptimizer("basicLMBFGS.xml");
      opt->setVerb(2);

      OptState state = opt->run(obj, xInit);

      bool ok = true;
      if (state.status() != Opt_Converged)
      {
        Out::root()<< "optimization failed: " << state.status() << endl;
        TEUCHOS_TEST_FOR_EXCEPT(state.status() != Opt_Converged);
      }

      Out::root() << "opt converged: " << state.iter() << " iterations"
                  << endl;
      Out::root() << "exact solution: U0=" << U0 << " A0=" << A0 << endl;
      FieldWriter w = new VTKWriter("PoissonSourceInversion");
      w.addMesh(mesh);
      w.addField("u", new ExprFieldWrapper(u0));
      w.addField("alpha", new ExprFieldWrapper(alpha0));
      w.addField("lambda", new ExprFieldWrapper(lambda0));
      w.write();
      
      
      double uErr = L2Norm(mesh, interior, u0-U0*uStar, q4);
      double aErr = L2Norm(mesh, interior, alpha0-A0*uStar, q4);
      Out::root() << "error in u = " << uErr << endl;
      Out::root() << "error in alpha = " << aErr << endl;

      double tol = 0.01;
      Sundance::passFailTest(uErr + aErr, tol);
    }
	catch(std::exception& e)
		{
      cerr << "main() caught exception: " << e.what() << endl;
		}
	Sundance::finalize();
  return Sundance::testStatus(); 
}
bool NonlinReducedIntegration()
{
  int np = MPIComm::world().getNProc();

  int n = 4;
  bool increaseProbSize = true;
  if ( (np % 4)==0 ) increaseProbSize = false;

  Array<double> h;
  Array<double> errQuad;
  Array<double> errReduced;

  for (int i=0; i<4; i++)
  {
    n *= 2;
    int nx = n;
    int ny = n;

    VectorType<double> vecType = new EpetraVectorType();

    MeshType meshType = new BasicSimplicialMeshType();
      
    int npx = -1;
    int npy = -1;
    PartitionedRectangleMesher::balanceXY(np, &npx, &npy);
    TEUCHOS_TEST_FOR_EXCEPT(npx < 1);
    TEUCHOS_TEST_FOR_EXCEPT(npy < 1);
    TEUCHOS_TEST_FOR_EXCEPT(npx * npy != np);
    if (increaseProbSize)
    {
      nx = nx*npx;
      ny = ny*npy;
    }
    MeshSource mesher = new PartitionedRectangleMesher(0.0, 1.0, nx, npx, 
      0.0,  1.0, ny, npy, meshType);
    Mesh mesh = mesher.getMesh();


    WatchFlag watchMe("watch eqn");
    watchMe.setParam("integration setup", 0);
    watchMe.setParam("integration", 0);
    watchMe.setParam("fill", 0);
    watchMe.setParam("evaluation", 0);
    watchMe.deactivate();

    WatchFlag watchBC("watch BCs");
    watchBC.setParam("integration setup", 0);
    watchBC.setParam("integration", 0);
    watchBC.setParam("fill", 0);
    watchBC.setParam("evaluation", 0);
    watchBC.deactivate();
    


    CellFilter interior = new MaximalCellFilter();
    CellFilter edges = new DimensionalCellFilter(1);

    CellFilter left = edges.subset(new CoordinateValueCellPredicate(0,0.0));
    CellFilter right = edges.subset(new CoordinateValueCellPredicate(0,1.0));
    CellFilter top = edges.subset(new CoordinateValueCellPredicate(1,1.0));
    CellFilter bottom = edges.subset(new CoordinateValueCellPredicate(1,0.0));

    BasisFamily basis = new Lagrange(1);
    Expr u = new UnknownFunction(basis, "u");
    Expr v = new TestFunction(basis, "v");

    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);

    QuadratureFamily quad = new ReducedQuadrature();
    QuadratureFamily quad2 = new GaussianQuadrature(2);

    /* Define the weak form */
    const double pi = 4.0*atan(1.0);

    Expr c = cos(pi*x);
    Expr s = sin(pi*x);
    Expr ch = cosh(y);
    Expr sh = sinh(y);
    Expr s2 = s*s; 
    Expr c2 = c*c;
    Expr sh2 = sh*sh;
    Expr ch2 = ch*ch;
    Expr pi2 = pi*pi;
    Expr uEx = s*ch;
    Expr eu = exp(uEx);
    Expr f = -(ch*eu*(-1 + pi2)*s) + ch2*(c2*eu*pi2 - s2) + eu*s2*sh2;

    Expr eqn = Integral(interior, exp(u)*(grad*u)*(grad*v)
      + v*f + v*u*u, quad, watchMe)
      + Integral(right, v*exp(u)*pi*cosh(y), quad,watchBC);
    /* Define the Dirichlet BC */
    Expr bc = EssentialBC(left+top, v*(u-uEx), quad, watchBC);

    Expr eqn2 = Integral(interior, exp(u)*(grad*u)*(grad*v)
      + v*f + v*u*u, quad2, watchMe)
      + Integral(right, v*exp(u)*pi*cosh(y), quad2,watchBC);
    /* Define the Dirichlet BC */
    Expr bc2 = EssentialBC(left+top, v*(u-uEx), quad2, watchBC);


    DiscreteSpace discSpace(mesh, new Lagrange(1), vecType);
    Expr soln1 = new DiscreteFunction(discSpace, 0.0, "u0");
    Expr soln2 = new DiscreteFunction(discSpace, 0.0, "u0");
    L2Projector proj(discSpace, uEx);
    Expr uEx0 = proj.project();

    NonlinearProblem nlp(mesh, eqn, bc, v, u, soln1, vecType);
    NonlinearProblem nlp2(mesh, eqn2, bc2, v, u, soln2, vecType);
    
    ParameterXMLFileReader reader("nox-aztec.xml");
    ParameterList noxParams = reader.getParameters();
    NOXSolver solver(noxParams);
    nlp.solve(solver);
    nlp2.solve(solver);

    FieldWriter w = new VTKWriter("NonlinReduced-n" + Teuchos::toString(n));
    w.addMesh(mesh);
    w.addField("soln1", new ExprFieldWrapper(soln1[0]));
    w.addField("soln2", new ExprFieldWrapper(soln2[0]));
    w.addField("exact", new ExprFieldWrapper(uEx0[0]));
    w.write();

    Expr err1 = uEx - soln1;
    Expr errExpr1 = Integral(interior, 
      err1*err1,
      new GaussianQuadrature(4));

    Expr err2 = uEx - soln2;
    Expr errExpr2 = Integral(interior, 
      err2*err2,
      new GaussianQuadrature(4));

    Expr err12 = soln2 - soln1;
    Expr errExpr12 = Integral(interior, 
      err12*err12,
      new GaussianQuadrature(4));
      
    double error1 = ::sqrt(evaluateIntegral(mesh, errExpr1));
    double error2 = ::sqrt(evaluateIntegral(mesh, errExpr2));
    double error12 = ::sqrt(evaluateIntegral(mesh, errExpr12));

    Out::root() << "final result: " << n << " "  << error1 << " " << error2 << " " << error12
                << endl;
        
    h.append(1.0/((double) n));
    errQuad.append(error2);
    errReduced.append(error1);
  }
    
  double pQuad = fitPower(h, errQuad);
  double pRed = fitPower(h, errReduced);
  Out::root() << "exponent (reduced integration) " << pRed << endl;
  Out::root() << "exponent (full integration) " << pQuad << endl;
    

  return SundanceGlobal::checkTest(::fabs(pRed-2.0), 0.1);

}