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

Site Contact