Belos Package Browser (Single Doxygen Collection) Development
BelosOrthoManagerFactory.hpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 //
00004 //                 Belos: Block Linear Solvers Package
00005 //                  Copyright 2004 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 Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ************************************************************************
00040 //@HEADER
00041 
00042 #ifndef __Belos_OrthoManagerFactory_hpp
00043 #define __Belos_OrthoManagerFactory_hpp
00044 
00045 #include <BelosConfigDefs.hpp>
00046 #ifdef HAVE_BELOS_TSQR
00047 #  include <BelosTsqrOrthoManager.hpp>
00048 #endif // HAVE_BELOS_TSQR
00049 #include <BelosICGSOrthoManager.hpp>
00050 #include <BelosIMGSOrthoManager.hpp>
00051 #include <BelosDGKSOrthoManager.hpp>
00052 #include <BelosSimpleOrthoManager.hpp>
00053 #include <BelosOutputManager.hpp>
00054 
00055 #include <Teuchos_StandardCatchMacros.hpp>
00056 
00057 #include <algorithm>
00058 #include <sstream>
00059 #include <stdexcept> // #include <string>
00060 #include <vector>
00061 
00063 
00064 namespace Belos {
00065 
00081   template<class Scalar, class MV, class OP>
00082   class OrthoManagerFactory {
00083   private:
00085     std::vector<std::string> theList_;
00086 
00087   public:
00089     static int numOrthoManagers () {
00090 #ifdef HAVE_BELOS_TSQR
00091       return 5; 
00092 #else
00093       return 4;
00094 #endif // HAVE_BELOS_TSQR
00095     }
00096 
00102     static bool isRankRevealing (const std::string& name) {
00103 #ifdef HAVE_BELOS_TSQR
00104       // Currently only TSQR has a full rank-revealing capability.
00105       return (name == "TSQR");
00106 #else
00107       return false;
00108 #endif // HAVE_BELOS_TSQR
00109     }
00110 
00112     OrthoManagerFactory () : theList_ (numOrthoManagers())
00113     {
00114       int index = 0;
00115       theList_[index++] = "DGKS";
00116       theList_[index++] = "ICGS";
00117       theList_[index++] = "IMGS";
00118 #ifdef HAVE_BELOS_TSQR
00119       theList_[index++] = "TSQR";
00120 #endif // HAVE_BELOS_TSQR
00121       theList_[index++] = "Simple";
00122     }
00123 
00132     const std::vector<std::string>& 
00133     validNames () const { return theList_; }
00134 
00136     bool
00137     isValidName (const std::string& name) const 
00138     {
00139       return (std::find (theList_.begin(), theList_.end(), name) != theList_.end());
00140     }
00141 
00143     std::ostream&
00144     printValidNames (std::ostream& out) const
00145     {
00146       const int numValid = numOrthoManagers();
00147       TEUCHOS_TEST_FOR_EXCEPTION(numValid <= 0, std::logic_error,
00148        "Invalid number " << numValid << " of valid MatOrtho"
00149        "Manager names.  Please report this bug to the Belos "
00150        "developers." );
00151       if (numValid > 1) {
00152   for (int k = 0; k < numValid - 1; ++k)
00153     out << "\"" << theList_[k] << "\", ";
00154   out << "or ";
00155       }
00156       out << "\"" << theList_[numValid-1] << "\"";
00157       return out;
00158     }
00159 
00164     std::string
00165     validNamesString () const
00166     {
00167       std::ostringstream os;
00168       (void) printValidNames (os);
00169       return os.str();
00170     }
00171 
00178     const std::string& defaultName () const { return theList_[0]; }
00179 
00189     Teuchos::RCP<const Teuchos::ParameterList> 
00190     getDefaultParameters (const std::string& name) const
00191     {
00192       if (name == "DGKS") {
00193   DGKSOrthoManager<Scalar, MV, OP> orthoMan;
00194   return orthoMan.getValidParameters ();
00195       }
00196 #ifdef HAVE_BELOS_TSQR
00197       else if (name == "TSQR") {
00198   TsqrMatOrthoManager<Scalar, MV, OP> orthoMan;
00199   return orthoMan.getValidParameters ();
00200       }
00201 #endif // HAVE_BELOS_TSQR
00202       else if (name == "ICGS") {
00203   ICGSOrthoManager<Scalar, MV, OP> orthoMan;
00204   return orthoMan.getValidParameters ();
00205       }
00206       else if (name == "IMGS") {
00207   IMGSOrthoManager<Scalar, MV, OP> orthoMan;
00208   return orthoMan.getValidParameters ();
00209       }
00210       else if (name == "Simple") {
00211   IMGSOrthoManager<Scalar, MV, OP> orthoMan;
00212   return orthoMan.getValidParameters ();
00213       }
00214       else {
00215   TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 
00216          "Invalid orthogonalization manager name \"" << name 
00217          << "\": Valid names are " << validNamesString() 
00218          << ".  For many of the test executables, the "
00219          "orthogonalization manager name often corresponds "
00220          "to the \"ortho\" command-line argument.");
00221   // Placate the compiler if necessary; we should never reach
00222   // this point.
00223   return Teuchos::null; 
00224       }
00225     }
00226 
00240     Teuchos::RCP<const Teuchos::ParameterList> 
00241     getFastParameters (const std::string& name) const
00242     {
00243       if (name == "DGKS") {
00244   DGKSOrthoManager<Scalar, MV, OP> orthoMan;
00245   return orthoMan.getFastParameters ();
00246       }
00247 #ifdef HAVE_BELOS_TSQR
00248       else if (name == "TSQR") {
00249   TsqrMatOrthoManager<Scalar, MV, OP> orthoMan; 
00250   return orthoMan.getFastParameters ();
00251       }
00252 #endif // HAVE_BELOS_TSQR
00253       else if (name == "ICGS") {
00254   ICGSOrthoManager<Scalar, MV, OP> orthoMan;
00255   return orthoMan.getFastParameters ();
00256       }
00257       else if (name == "IMGS") {
00258   IMGSOrthoManager<Scalar, MV, OP> orthoMan;
00259   return orthoMan.getFastParameters ();
00260       }
00261       else if (name == "Simple") {
00262   IMGSOrthoManager<Scalar, MV, OP> orthoMan;
00263   return orthoMan.getFastParameters ();
00264       }
00265       else {
00266   TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 
00267          "Invalid orthogonalization manager name \"" << name 
00268          << "\": Valid names are " << validNamesString() 
00269          << ".  For many of the test executables, the "
00270          "orthogonalization manager name often corresponds "
00271          "to the \"ortho\" command-line argument.");
00272   // Placate the compiler if necessary; we should never reach
00273   // this point.
00274   return Teuchos::null; 
00275       }
00276     }
00277 
00297     Teuchos::RCP<Belos::MatOrthoManager<Scalar, MV, OP> >
00298     makeMatOrthoManager (const std::string& ortho, 
00299        const Teuchos::RCP<const OP>& M,
00300        const Teuchos::RCP<OutputManager<Scalar> >& outMan,
00301        const std::string& label,
00302        const Teuchos::RCP<Teuchos::ParameterList>& params)
00303     {
00304 #ifdef HAVE_BELOS_TSQR
00305       using Belos::TsqrMatOrthoManager;
00306 #endif // HAVE_BELOS_TSQR
00307       using Belos::ICGSOrthoManager;
00308       using Belos::IMGSOrthoManager;
00309       using Belos::DGKSOrthoManager;
00310       using Belos::SimpleOrthoManager;
00311       using Teuchos::rcp;
00312       typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type;
00313 
00314       if (ortho == "DGKS") {
00315   typedef DGKSOrthoManager<Scalar, MV, OP> dgks_type;
00316   return rcp (new dgks_type (params, label, M));
00317       }
00318 #ifdef HAVE_BELOS_TSQR
00319       else if (ortho == "TSQR") {
00320   typedef TsqrMatOrthoManager<Scalar, MV, OP> ortho_type;
00321   return rcp (new ortho_type (params, label, M));
00322       }
00323 #endif // HAVE_BELOS_TSQR
00324       else if (ortho == "ICGS") {
00325   typedef ICGSOrthoManager<Scalar, MV, OP> ortho_type;
00326   return rcp (new ortho_type (params, label, M));
00327       }
00328       else if (ortho == "IMGS") {
00329   typedef IMGSOrthoManager<Scalar, MV, OP> ortho_type;
00330   return rcp (new ortho_type (params, label, M));
00331       } 
00332       else if (ortho == "Simple") {
00333   TEUCHOS_TEST_FOR_EXCEPTION(ortho == "Simple", std::logic_error,
00334            "SimpleOrthoManager does not yet support "
00335            "the MatOrthoManager interface");
00336       } 
00337       TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 
00338          "Invalid orthogonalization manager name: Valid names"
00339          " are " << validNamesString() << ".  For many of "
00340          "the test executables, the orthogonalization manager"
00341          " name often corresponds to the \"ortho\" command-"
00342          "line argument.");
00343       return Teuchos::null; // Guard to avoid compiler warnings.
00344     }
00345 
00362     Teuchos::RCP<Belos::OrthoManager<Scalar, MV> >
00363     makeOrthoManager (const std::string& ortho, 
00364           const Teuchos::RCP<const OP>& M,
00365           const Teuchos::RCP<OutputManager<Scalar> >& outMan,
00366           const std::string& label,
00367           const Teuchos::RCP<Teuchos::ParameterList>& params)
00368     {
00369 #ifdef HAVE_BELOS_TSQR
00370       using Belos::TsqrOrthoManager;
00371 #endif // HAVE_BELOS_TSQR
00372       using Teuchos::rcp;
00373 
00374       if (ortho == "Simple") {
00375   TEUCHOS_TEST_FOR_EXCEPTION(! M.is_null(), std::logic_error,
00376            "SimpleOrthoManager is not yet supported "
00377            "when the operator M is nontrivial (i.e., "
00378            "M != null).");
00379   return rcp (new SimpleOrthoManager<Scalar, MV> (outMan, label, params));
00380       }
00381 #ifdef HAVE_BELOS_TSQR
00382       // TsqrMatOrthoManager has to store more things and do more work
00383       // than TsqrOrthoManager, in order for the former to be correct
00384       // for the case of a nondefault (non-Euclidean) inner product.
00385       // Thus, it's better to create a TsqrOrthoManager, when we know
00386       // the operator is the default operator (M is null).  Of course,
00387       // a MatOrthoManager is-an OrthoManager, so returning a
00388       // TsqrMatOrthoManager would still be correct; this is just an
00389       // optimization.
00390       else if (ortho == "TSQR" && M.is_null()) {
00391   return rcp (new TsqrOrthoManager<Scalar, MV> (params, label));
00392       }
00393 #endif // HAVE_BELOS_TSQR
00394       else {
00395   // A MatOrthoManager is-an OrthoManager.
00396   return makeMatOrthoManager (ortho, M, outMan, label, params);
00397       }
00398     }
00399   };
00400 
00401 } // namespace Belos
00402 
00403 #endif // __Belos_OrthoManagerFactory_hpp
00404 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines