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 /** */
00118 class LPTestSpec
00119 {
00120 public:
00121   /** */
00122   LPTestSpec() {;}
00123   /** */
00124   LPTestSpec(const std::string& solverFile, double tol)
00125     : hasProcRestriction_(false), allowedProcNumbers_(),
00126       solverFile_(solverFile), tol_(tol){}
00127 
00128   /** */
00129   LPTestSpec(const std::string& solverFile, double tol, 
00130     const Set<int>& allowedProcs) 
00131     : hasProcRestriction_(true), allowedProcNumbers_(allowedProcs),
00132       solverFile_(solverFile), tol_(tol){}
00133 
00134   /** */
00135   const double& tol() const {return tol_;}
00136 
00137   /** */
00138   const std::string& solverFile() const {return solverFile_;}
00139 
00140   /** */
00141   bool nProcIsAllowed(int np) const
00142     {
00143       if (!hasProcRestriction_) return true;
00144       return allowedProcNumbers_.contains(np);
00145     }
00146 
00147 private:
00148   bool hasProcRestriction_;
00149 
00150   Set<int> allowedProcNumbers_;
00151 
00152   std::string solverFile_;
00153 
00154   double tol_;
00155 };
00156 
00157 
00158 /** \relates LPTestSpec */
00159 std::ostream& operator<<(std::ostream& os, const LPTestSpec& spec);
00160 
00161 class ForwardProblemTestBase;
00162 
00163 /**
00164  * Base class for objects that compute error norms. 
00165  */
00166 class ErrNormCalculatorBase
00167 {
00168 public:
00169   /** Compute the error norm. In vector-valued problems we may need to
00170    * compute multiple norms, so the return type is an array. */
00171   virtual Array<double> computeNorms(const ForwardProblemTestBase* prob,
00172     int meshIndex,
00173     const Expr& numSoln, const Expr& exactSoln) const = 0 ;
00174 };
00175 
00176 /**
00177  * Object to compute L2 norms of errors 
00178  */
00179 class L2NormCalculator : public ErrNormCalculatorBase
00180 {
00181 public:
00182   /** */
00183   L2NormCalculator() {}
00184 
00185   /** */
00186   virtual Array<double> computeNorms(const ForwardProblemTestBase* prob,
00187     int meshIndex,
00188     const Expr& numSoln, const Expr& exactSoln) const ;
00189 
00190 };
00191 
00192 /** 
00193  * 
00194  */
00195 class ForwardProblemTestBase
00196 {
00197 public:
00198   /** */
00199   virtual bool run(const std::string& solverFile, double tol) const ;
00200 
00201   /** */
00202   virtual std::string name() const = 0 ;
00203 
00204   /** */
00205   virtual Expr exactSoln() const = 0 ;
00206 
00207   /** */
00208   virtual VectorType<double> vecType() const ;
00209 
00210   /** */
00211   virtual Expr coord(int d) const ;
00212 
00213   /** */
00214   virtual Mesh getMesh(int i) const = 0 ;
00215 
00216   /** */
00217   virtual CellFilter interior() const = 0 ;
00218 
00219   /** */
00220   virtual RCP<ErrNormCalculatorBase> normCalculator() const ;
00221 
00222   /** 
00223    * Solve the problem on the \f$i\f$-th mesh. Return a bool indicating whether
00224    * the solve succeeded. 
00225    */
00226   virtual bool solve(const Mesh& mesh, const LinearSolver<double>& solver,
00227     Expr& soln) const = 0 ;
00228 
00229   /** */
00230   virtual int numMeshes() const = 0 ;
00231 
00232   /** 
00233    * Return the average cell size on the \f$i\f$-th mesh.
00234    */
00235   virtual double cellSize(int i) const ;
00236 
00237   /** 
00238    * Return the order of accuracy expected for the solution. If the problem
00239    * is vector-valued, an array of expected orders is returned.  
00240    */
00241   virtual Array<int> pExpected() const = 0 ;
00242 
00243 private:
00244   /** */
00245   bool runSingleTest(const std::string& solverFile, const double& tol) const ;
00246 
00247   /** */
00248   bool runTestSequence(const std::string& solverFile, const double& tol) const ;
00249 };
00250 
00251 /** */
00252 class LPTestBase : public ForwardProblemTestBase
00253 {
00254 public:
00255 
00256   /** */
00257   virtual Array<LPTestSpec> specs() const ;
00258 
00259   /** */
00260   virtual LinearProblem prob(const Mesh& mesh) const = 0 ;
00261 
00262   /** */
00263   virtual bool solve(const Mesh& mesh, 
00264     const LinearSolver<double>& solver,
00265     Expr& soln) const ;
00266 };
00267 
00268 
00269 
00270 /** */
00271 class LP1DTestBase : public LPTestBase
00272 {
00273 public:
00274   /** */
00275   LP1DTestBase(const Array<int>& nx);
00276 
00277   /** */
00278   LP1DTestBase(double a, double b, const Array<int>& nx);
00279 
00280   /** */
00281   CellFilter interior() const {return domain_.interior();}
00282 
00283   /** */
00284   Mesh getMesh(int i) const {return domain_.mesh(i);}
00285 
00286   /** */
00287   const LineDomain& domain() const {return domain_;}
00288 
00289   /** */
00290   int numMeshes() const {return domain_.numMeshes();}
00291   
00292 private:
00293   LineDomain domain_;
00294 };
00295 
00296 
00297 /** */
00298 class LPTestSuite
00299 {
00300 public:
00301   /** */
00302   LPTestSuite();
00303 
00304   /** */
00305   void registerTest(const RCP<LPTestBase>& test) ;
00306 
00307   /** */
00308   bool run() const ;
00309   
00310 private:
00311   Array<RCP<LPTestBase> > tests_;
00312   Array<Array<LPTestSpec> > testSpecs_;
00313 };
00314 
00315 
00316 }
00317 
00318 #endif
00319 

Site Contact