Coupled2D.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 
00031 #include "Sundance.hpp"
00032 
00033 using Sundance::List;
00034 
00035 
00036 /** 
00037  * Solves the coupled equations
00038  *
00039  * \f[\nabla^2 u_1 = u_2 \f]
00040  * \f[\nabla^2 u_2 = x \f]
00041  * \f[u_1 = u_2 = 0\;\;\;\mathrm{on\; east\; and\; west}\f]
00042  * \f[\frac{\partial u_1}{\partial n} = \frac{\partial u_2}{\partial n} = 0\;\;\;\mathrm{on\; north\; and\; south}\f]
00043  * 
00044  *
00045  * The solution is
00046  * \f[u_1(x,y)=\frac{1}{360}(3 x^5 - 10 x^3 + 7 x)\f]
00047  * \f[u_2(x,y)= \frac{1}{6} x (x^2-1)\f]
00048  *
00049  * 
00050  */
00051 
00052 int main(int argc, char** argv)
00053 {
00054   
00055   try
00056     {
00057       Sundance::init(&argc, &argv);
00058 
00059       /* We will do our linear algebra using Epetra */
00060       VectorType<double> vecType = new EpetraVectorType();
00061 
00062       /* Create a mesh. It will be of type BasisSimplicialMesh, and will
00063        * be built using a PartitionedRectangleMesher. */
00064       MeshType meshType = new BasicSimplicialMeshType();
00065       int nx = 32;
00066 
00067       MeshSource mesher = new PartitionedRectangleMesher(0.0, 1.0, nx,
00068         0.0, 2.0, nx,
00069         meshType);
00070       Mesh mesh = mesher.getMesh();
00071 
00072       /* Create a cell filter that will identify the maximal cells
00073        * in the interior of the domain */
00074       CellFilter interior = new MaximalCellFilter();
00075 
00076       /* Create cell filters for the boundary surfaces */
00077       CellFilter edges = new DimensionalCellFilter(1);
00078 
00079       CellFilter west = edges.coordSubset(0, 0.0);
00080       CellFilter east = edges.coordSubset(0, 1.0);
00081 
00082       
00083       /* Create unknown and test functions, discretized using first-order
00084        * Lagrange interpolants */
00085       Expr u1 = new UnknownFunction(new Lagrange(3), "u");
00086       Expr u2 = new UnknownFunction(new Lagrange(2), "v");
00087       Expr du1 = new TestFunction(new Lagrange(3), "du");
00088       Expr du2 = new TestFunction(new Lagrange(2), "dv");
00089 
00090       /* Create differential operator and coordinate function */
00091       Expr dx = new Derivative(0);
00092       Expr x = new CoordExpr(0);
00093       Expr dy = new Derivative(1);
00094       Expr y = new CoordExpr(1);
00095       Expr grad = List(dx, dy);
00096 
00097       /* We need a quadrature rule for doing the integrations */
00098       QuadratureFamily quad = new GaussianQuadrature(6);
00099 
00100       
00101       /* Define the weak form */
00102       Expr eqn = Integral(interior, 
00103                           (grad*du1)*(grad*u1) + du1*u2 + (grad*du2)*(grad*u2) + x*du2, 
00104                           quad);
00105       /* Define the Dirichlet BC */
00106       Expr bc = EssentialBC(east + west, du1*u1 + du2*u2, quad);
00107 
00108       /* We can now set up the linear problem! The order of the test functions in the
00109       * list determines the order of these variables in the matrix. Liewise for
00110       * the unknown functions. */
00111       LinearProblem prob(mesh, eqn, bc, List(du1,du2), List(u1,u2), vecType);
00112 
00113       
00114 
00115       /* Get a solver */
00116       LinearSolver<double> solver = LinearSolverBuilder::createSolver("aztec-ml.xml");
00117 
00118 
00119       /* Solver */
00120       Expr soln = prob.solve(solver);
00121 
00122       /* Check */
00123       Expr x2 = x*x;
00124       Expr x3 = x*x2;
00125 
00126       Expr u1Exact = (1.0/120.0)*x2*x3 - 1.0/36.0 * x3 + 7.0/360.0 * x;
00127       Expr u2Exact = 1.0/6.0 * x * (x2 - 1.0);
00128 
00129       Expr u1Err = u1Exact - soln[0];
00130       Expr u2Err = u2Exact - soln[1];
00131       
00132       double u1ErrorNorm = L2Norm(mesh, interior, u1Err, quad);
00133       std::cerr << "u1 error norm = " << u1ErrorNorm << std::endl << std::endl;
00134 
00135       double u2ErrorNorm = L2Norm(mesh, interior, u2Err, quad);
00136       std::cerr << "u2 error norm = " << u2ErrorNorm << std::endl << std::endl;
00137 
00138 
00139       
00140       /* Write the field in VTK format */
00141       FieldWriter w = new VTKWriter("Coupled2D");
00142       w.addMesh(mesh);
00143       w.addField("v", new ExprFieldWrapper(soln[0]));
00144       w.addField("u", new ExprFieldWrapper(soln[1]));
00145       w.write();
00146 
00147 
00148 
00149       double tol = 1.0e-5;
00150       Sundance::passFailTest(max(u1ErrorNorm, u2ErrorNorm), tol);
00151     }
00152   catch(std::exception& e)
00153     {
00154       Sundance::handleException(e);
00155     }
00156   Sundance::finalize(); 
00157   return Sundance::testStatus(); 
00158 }

Site Contact