StepControlledTransientNonlinear1D.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #include "Sundance.hpp"
00043 #include "SundanceTransientStepProblem.hpp"
00044 #include "SundanceDoublingStepController.hpp"
00045 #include "SundanceProblemTesting.hpp"
00046 
00047 Expr rhsF(const Expr& x, const Expr& t)
00048 {
00049   return -12*pow((1 - x)*cos(t) - x*cos(t),2)
00050     *pow(2 + (1 - x)*x*cos(t),2) + 
00051     8*cos(t)*pow(2 + (1 - x)*x*cos(t),3) - (1 - x)*x*sin(t);
00052 }
00053 
00054 
00055 int main(int argc, char** argv)
00056 {
00057   try
00058   {
00059     int nx = 96;
00060 
00061     Sundance::setOption("nx", nx, "Number of elements");
00062 
00063     Sundance::init(&argc, &argv);
00064     int np = MPIComm::world().getNProc();
00065 
00066     /* We will do our linear algebra using Epetra */
00067     VectorType<double> vecType = new EpetraVectorType();
00068 
00069     /* Create a mesh. It will be of type BasisSimplicialMesh, and will
00070      * be built using a PartitionedLineMesher. */
00071     MeshType meshType = new BasicSimplicialMeshType();
00072     MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx*np, meshType);
00073     Mesh mesh = mesher.getMesh();
00074 
00075     /* Create a cell filter that will identify the maximal cells
00076      * in the interior of the domain */
00077     CellFilter interior = new MaximalCellFilter();
00078     CellFilter points = new DimensionalCellFilter(0);
00079 
00080     CellFilter right = points.coordSubset(0, 0.0);
00081     CellFilter left = points.coordSubset(0, 1.0);
00082     CellFilter midpoint = points.coordSubset(0, 0.5);
00083       
00084     /* Create unknown and test functions, discretized using first-order
00085      * Lagrange interpolants */
00086     BasisFamily basis = new Lagrange(1);
00087     Expr u = new UnknownFunction(basis, "u");
00088     Expr v = new TestFunction(basis, "v");
00089 
00090     
00091 
00092     /* Create differential operator and coordinate function */
00093     Expr dx = new Derivative(0);
00094     Expr x = new CoordExpr(0);
00095     
00096     /* We need a quadrature rule for doing the integrations */
00097     QuadratureFamily quad = new GaussianQuadrature(4);
00098 
00099     
00100     Expr tPrev = new Sundance::Parameter(0.0);
00101     Expr t = new Sundance::Parameter(0.0);
00102     Expr dt = new Sundance::Parameter(0.0);
00103 
00104     DiscreteSpace ds(mesh, basis, vecType);
00105     L2Projector proj(ds, 2.0+x*(1.0-x)*cos(t));
00106     Expr uPrev = proj.project();
00107     Expr uSoln = copyDiscreteFunction(uPrev);
00108 
00109     Expr eqn = Integral(interior, v*(u-uPrev) 
00110       + 2.0*dt*(dx*v)*(pow(u,3.0)*(dx*u) + pow(uPrev, 3.0)*(dx*uPrev))
00111       - 0.5*dt*v*(rhsF(x, tPrev) + rhsF(x, t)),
00112       quad);
00113     Expr bc = EssentialBC(left+right, v*(u+uPrev-4.0), quad);
00114 
00115     NonlinearProblem stepProb(mesh, eqn, bc, v, u, uSoln, vecType);
00116 
00117     TransientStepProblem prob(stepProb, tPrev, uPrev, t, uSoln, dt, 0);
00118 
00119     /* Use the Playa Newton-Armijo nonlinear solver */
00120     NonlinearSolver<double> solver 
00121       = NonlinearSolverBuilder::createSolver("playa-newton-aztec-ml.xml");
00122 
00123     double tol = 1.0e-4;
00124     double tFinal = 3.0*M_PI;
00125     StepControlParameters stepControl;
00126     stepControl.tStart_ = 0.0;
00127     stepControl.tStop_ = tFinal;
00128     stepControl.initialStepsize_ = 0.1;
00129     stepControl.maxStepsizeFactor_ = 100.0;
00130     stepControl.minStepsizeFactor_ = 1.0e-4;
00131     stepControl.verbosity_ = 4;
00132     stepControl.tau_ = tol;
00133 
00134     FieldWriterFactory wf = new DSVWriterFactory();
00135     OutputControlParameters outputControl(wf, "ControlledTransient1D", tFinal/100.0, 0);
00136 
00137     RCP<ExprComparisonBase> compare = rcp(new DefaultExprComparison());
00138     
00139     DoublingStepController driver(prob, solver, stepControl, outputControl,
00140       compare);
00141 
00142     driver.run();
00143 
00144     Expr uFinal = copyDiscreteFunction(prob.uSoln());
00145     Expr uExact = 2.0 + x*(1.0-x)*cos(tFinal);
00146 
00147     Expr errExpr = Integral(interior, 
00148       pow(uFinal-uExact, 2),
00149       new GaussianQuadrature(2));
00150     double error = sqrt(evaluateIntegral(mesh, errExpr));
00151 
00152     Out::root() << "error = " << error << endl;
00153     
00154 
00155     Sundance::passFailTest(error, tol);
00156   }
00157   catch(std::exception& e)
00158   {
00159     std::cerr << e.what() << std::endl;
00160   }
00161   Sundance::finalize(); return Sundance::testStatus(); 
00162 }
00163 
00164 
00165 

Site Contact