SundanceProblemTesting.hpp
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 #ifndef SUNDANCE_PROBLEMTESTING_H
00032 #define SUNDANCE_PROBLEMTESTING_H
00033 
00034 #include "SundanceFunctional.hpp"
00035 #include "SundanceLinearProblem.hpp"
00036 
00037 namespace Sundance
00038 {
00039 
00040 using namespace Teuchos;
00041 
00042 
00043 /** 
00044  * This function checks the L2 and H1 norms and the H1 seminorm of
00045  * an error against a specified tolerance.
00046  */
00047 bool checkErrorNorms(
00048   const Mesh& mesh,
00049   const CellFilter& filter,
00050   const Expr& numSoln,
00051   const Expr& exactSoln,
00052   const QuadratureFamily& quad,
00053   double L2Tol,
00054   double H1SemiTol,
00055   double H1Tol);
00056 
00057 /** 
00058  * Compute the exponent \f$p\f$ that best fits the measured errors to a 
00059  * power law \f$\epsilon=A h^p\f$. 
00060  */
00061 double fitPower(const Array<double>& h, const Array<double>& err);
00062 
00063 
00064 /** 
00065  * This class bundles together a sequence of uniform meshes
00066  * of the 1D interval [a,b] with cell
00067  * filters defining the interior and boundaries. It is intended for quick 
00068  * and reliable setup of 1D test problems.
00069  */
00070 class LineDomain
00071 {
00072 public:
00073   /** */
00074   LineDomain(const Array<int>& nx);
00075 
00076   /** */
00077   LineDomain(double a, double b, const Array<int>& nx);
00078 
00079   /** */
00080   int numMeshes() const {return mesh_.size();}
00081 
00082   /** */
00083   const CellFilter& left() const {return left_;}
00084 
00085   /** */
00086   const CellFilter& right() const {return right_;}
00087 
00088   /** */
00089   const CellFilter& interior() const {return interior_;}
00090 
00091   /** */
00092   const Mesh& mesh(int i) const {return mesh_[i];}
00093 
00094   /** */
00095   double a() const {return a_;}
00096 
00097   /** */
00098   double b() const {return b_;}
00099   
00100   /** */
00101   int nx(int i) const {return nx_[i];}
00102 
00103 private:
00104   void init();
00105 
00106   double a_;
00107   double b_;
00108   Array<int> nx_;
00109   CellFilter interior_;
00110   CellFilter left_;
00111   CellFilter right_;
00112   Array<Mesh> mesh_;
00113 };
00114 
00115 
00116 /** 
00117  * This class bundles together a sequence of uniform meshes
00118  * of the 2D rectangle [ax,bx] times [ay,by] with cell
00119  * filters defining the interior and boundaries. It is intended for quick 
00120  * and reliable setup of 2D test problems.
00121  */
00122 class RectangleDomain
00123 {
00124 public:
00125   /** Contruct the unit square */
00126   RectangleDomain(const Array<int>& n);
00127 
00128   /** Construct */
00129   RectangleDomain(
00130     double ax, double bx, const Array<int>& nx,
00131     double ay, double by, const Array<int>& ny
00132     );
00133 
00134   /** */
00135   int numMeshes() const {return mesh_.size();}
00136 
00137   /** */
00138   const CellFilter& north() const {return north_;}
00139 
00140   /** */
00141   const CellFilter& south() const {return south_;}
00142 
00143   /** */
00144   const CellFilter& east() const {return east_;}
00145 
00146   /** */
00147   const CellFilter& west() const {return west_;}
00148 
00149   /** */
00150   const CellFilter& interior() const {return interior_;}
00151 
00152   /** */
00153   const Mesh& mesh(int i) const {return mesh_[i];}
00154 
00155   /** */
00156   double ax() const {return ax_;}
00157 
00158   /** */
00159   double bx() const {return bx_;}
00160   
00161   /** */
00162   int nx(int i) const {return nx_[i];}
00163 
00164   /** */
00165   double ay() const {return ay_;}
00166 
00167   /** */
00168   double by() const {return by_;}
00169   
00170   /** */
00171   int ny(int i) const {return ny_[i];}
00172 
00173 private:
00174   void init();
00175 
00176   double ax_;
00177   double bx_;
00178   Array<int> nx_;
00179   double ay_;
00180   double by_;
00181   Array<int> ny_;
00182   CellFilter interior_;
00183   CellFilter north_;
00184   CellFilter south_;
00185   CellFilter east_;
00186   CellFilter west_;
00187   Array<Mesh> mesh_;
00188 };
00189 
00190 
00191 
00192 /** */
00193 class LPTestSpec
00194 {
00195 public:
00196   /** */
00197   LPTestSpec() {;}
00198   /** */
00199   LPTestSpec(const std::string& solverFile, double tol)
00200     : hasProcRestriction_(false), allowedProcNumbers_(),
00201       solverFile_(solverFile), tol_(tol){}
00202 
00203   /** */
00204   LPTestSpec(const std::string& solverFile, double tol, 
00205     const Set<int>& allowedProcs) 
00206     : hasProcRestriction_(true), allowedProcNumbers_(allowedProcs),
00207       solverFile_(solverFile), tol_(tol){}
00208 
00209   /** */
00210   const double& tol() const {return tol_;}
00211 
00212   /** */
00213   const std::string& solverFile() const {return solverFile_;}
00214 
00215   /** */
00216   bool nProcIsAllowed(int np) const
00217     {
00218       if (!hasProcRestriction_) return true;
00219       return allowedProcNumbers_.contains(np);
00220     }
00221 
00222 private:
00223   bool hasProcRestriction_;
00224 
00225   Set<int> allowedProcNumbers_;
00226 
00227   std::string solverFile_;
00228 
00229   double tol_;
00230 };
00231 
00232 
00233 /** \relates LPTestSpec */
00234 std::ostream& operator<<(std::ostream& os, const LPTestSpec& spec);
00235 
00236 class ForwardProblemTestBase;
00237 
00238 /**
00239  * Base class for objects that compute error norms. 
00240  */
00241 class ErrNormCalculatorBase
00242 {
00243 public:
00244   /** Compute the error norm. In vector-valued problems we may need to
00245    * compute multiple norms, so the return type is an array. */
00246   virtual Array<double> computeNorms(const ForwardProblemTestBase* prob,
00247     int meshIndex,
00248     const Expr& numSoln, const Expr& exactSoln) const = 0 ;
00249 };
00250 
00251 /**
00252  * Object to compute L2 norms of errors 
00253  */
00254 class L2NormCalculator : public ErrNormCalculatorBase
00255 {
00256 public:
00257   /** */
00258   L2NormCalculator() {}
00259 
00260   /** */
00261   virtual Array<double> computeNorms(const ForwardProblemTestBase* prob,
00262     int meshIndex,
00263     const Expr& numSoln, const Expr& exactSoln) const ;
00264 
00265 };
00266 
00267 /** 
00268  * 
00269  */
00270 class ForwardProblemTestBase
00271 {
00272 public:
00273   /** */
00274   virtual bool run(const std::string& solverFile, double tol) const ;
00275 
00276   /** */
00277   virtual std::string name() const = 0 ;
00278 
00279   /** */
00280   virtual Expr exactSoln() const = 0 ;
00281 
00282   /** */
00283   virtual VectorType<double> vecType() const ;
00284 
00285   /** */
00286   virtual Expr coord(int d) const ;
00287 
00288   /** */
00289   virtual Mesh getMesh(int i) const = 0 ;
00290 
00291   /** */
00292   virtual CellFilter interior() const = 0 ;
00293 
00294   /** */
00295   virtual RCP<ErrNormCalculatorBase> normCalculator() const ;
00296 
00297   /** 
00298    * Solve the problem on the \f$i\f$-th mesh. Return a bool indicating whether
00299    * the solve succeeded. 
00300    */
00301   virtual bool solve(const Mesh& mesh, const LinearSolver<double>& solver,
00302     Expr& soln) const = 0 ;
00303 
00304   /** */
00305   virtual int numMeshes() const = 0 ;
00306 
00307   /** 
00308    * Return the average cell size on the \f$i\f$-th mesh.
00309    */
00310   virtual double cellSize(int i) const ;
00311 
00312   /** 
00313    * Return the order of accuracy expected for the solution. If the problem
00314    * is vector-valued, an array of expected orders is returned.  
00315    */
00316   virtual Array<int> pExpected() const = 0 ;
00317 
00318   /** 
00319    * Hook for a user-defined operation after each run. This can be used,
00320    * for example, to write viz output. Default is a no-op.
00321    */
00322   virtual void postRunCallback(int meshID, const Mesh& mesh,
00323     const string& solverFile,
00324     const Expr& soln) const {} 
00325 
00326 private:
00327   /** */
00328   bool runSingleTest(const std::string& solverFile, const double& tol) const ;
00329 
00330   /** */
00331   bool runTestSequence(const std::string& solverFile, const double& tol) const ;
00332 };
00333 
00334 /** */
00335 class LPTestBase : public ForwardProblemTestBase
00336 {
00337 public:
00338 
00339   /** */
00340   virtual Array<LPTestSpec> specs() const ;
00341 
00342   /** */
00343   virtual LinearProblem prob(const Mesh& mesh) const = 0 ;
00344 
00345   /** */
00346   virtual bool solve(const Mesh& mesh, 
00347     const LinearSolver<double>& solver,
00348     Expr& soln) const ;
00349 };
00350 
00351 
00352 
00353 /** */
00354 class LP1DTestBase : public LPTestBase
00355 {
00356 public:
00357   /** */
00358   LP1DTestBase(const Array<int>& nx);
00359 
00360   /** */
00361   LP1DTestBase(double a, double b, const Array<int>& nx);
00362 
00363   /** */
00364   CellFilter interior() const {return domain_.interior();}
00365 
00366   /** */
00367   Mesh getMesh(int i) const {return domain_.mesh(i);}
00368 
00369   /** */
00370   const LineDomain& domain() const {return domain_;}
00371 
00372   /** */
00373   int numMeshes() const {return domain_.numMeshes();}
00374   
00375 private:
00376   LineDomain domain_;
00377 };
00378 
00379 
00380 /** */
00381 class LPRectTestBase : public LPTestBase
00382 {
00383 public:
00384   /** */
00385   LPRectTestBase(const Array<int>& n);
00386 
00387   /** */
00388   CellFilter interior() const {return domain_.interior();}
00389 
00390   /** */
00391   Mesh getMesh(int i) const {return domain_.mesh(i);}
00392 
00393   /** */
00394   const RectangleDomain& domain() const {return domain_;}
00395 
00396   /** */
00397   int numMeshes() const {return domain_.numMeshes();}
00398   
00399 private:
00400   RectangleDomain domain_;
00401 };
00402 
00403 
00404 /** */
00405 class LPTestSuite
00406 {
00407 public:
00408   /** */
00409   LPTestSuite();
00410 
00411   /** */
00412   void registerTest(const RCP<LPTestBase>& test) ;
00413 
00414   /** */
00415   bool run() const ;
00416   
00417 private:
00418   Array<RCP<LPTestBase> > tests_;
00419   Array<Array<LPTestSpec> > testSpecs_;
00420 };
00421 
00422 
00423 }
00424 
00425 #endif
00426 

Site Contact