Belos Version of the Day
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       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   {
00153     for (int k = 0; k < numValid - 1; ++k)
00154       out << "\"" << theList_[k] << "\", ";
00155     out << "or ";
00156   }
00157       out << "\"" << theList_[numValid-1] << "\"";
00158       return out;
00159     }
00160 
00165     std::string
00166     validNamesString () const
00167     {
00168       std::ostringstream os;
00169       (void) printValidNames (os);
00170       return os.str();
00171     }
00172 
00179     const std::string& defaultName () const { return theList_[0]; }
00180 
00190     Teuchos::RCP<const Teuchos::ParameterList> 
00191     getDefaultParameters (const std::string& name)
00192     {
00193       if (name == "DGKS") {
00194   return getDefaultDgksParameters<Scalar>();
00195       }
00196 #ifdef HAVE_BELOS_TSQR
00197       else if (name == "TSQR") {
00198   return TsqrMatOrthoManager<Scalar, MV, OP>::getDefaultParameters();
00199       }
00200 #endif // HAVE_BELOS_TSQR
00201       else if (name == "ICGS") {
00202   return getDefaultIcgsParameters<Scalar>();
00203       }
00204       else if (name == "IMGS") {
00205   return getDefaultImgsParameters<Scalar>();
00206       }
00207       else if (name == "Simple") {
00208   return SimpleOrthoManager<Scalar, MV>::getDefaultParameters();
00209       }
00210       else {
00211   TEST_FOR_EXCEPTION(true, std::invalid_argument, 
00212          "Invalid orthogonalization manager name \"" << name 
00213          << "\": Valid names are " << validNamesString() 
00214          << ".  For many of the test executables, the "
00215          "orthogonalization manager name often corresponds "
00216          "to the \"ortho\" command-line argument.");
00217   // Placate the compiler if necessary; we should never reach
00218   // this point.
00219   return Teuchos::null; 
00220       }
00221     }
00222 
00223 
00237     Teuchos::RCP<const Teuchos::ParameterList> 
00238     getFastParameters (const std::string& name)
00239     {
00240       if (name == "DGKS") {
00241   return getFastDgksParameters<Scalar>();
00242       }
00243 #ifdef HAVE_BELOS_TSQR
00244       else if (name == "TSQR") {
00245   return TsqrMatOrthoManager<Scalar, MV, OP>::getFastParameters();
00246       }
00247 #endif // HAVE_BELOS_TSQR
00248       else if (name == "ICGS") {
00249   return getFastIcgsParameters<Scalar>();
00250       }
00251       else if (name == "IMGS") {
00252   return getFastImgsParameters<Scalar>();
00253       }
00254       else if (name == "Simple") {
00255   return SimpleOrthoManager<Scalar, MV>::getFastParameters();
00256       }
00257       else {
00258   TEST_FOR_EXCEPTION(true, std::invalid_argument, 
00259          "Invalid orthogonalization manager name \"" << name 
00260          << "\": Valid names are " << validNamesString() 
00261          << ".  For many of the test executables, the "
00262          "orthogonalization manager name often corresponds "
00263          "to the \"ortho\" command-line argument.");
00264   // Placate the compiler if necessary; we should never reach
00265   // this point.
00266   return Teuchos::null; 
00267       }
00268     }
00269 
00270 
00292     Teuchos::RCP< Belos::MatOrthoManager<Scalar, MV, OP> >
00293     makeMatOrthoManager (const std::string& ortho, 
00294        const Teuchos::RCP<const OP>& M,
00295        const Teuchos::RCP<OutputManager<Scalar> >& outMan,
00296        const std::string& label,
00297        const Teuchos::RCP<const Teuchos::ParameterList>& params)
00298     {
00299 #ifdef HAVE_BELOS_TSQR
00300       using Belos::TsqrMatOrthoManager;
00301 #endif // HAVE_BELOS_TSQR
00302       using Belos::ICGSOrthoManager;
00303       using Belos::IMGSOrthoManager;
00304       using Belos::DGKSOrthoManager;
00305       using Belos::SimpleOrthoManager;
00306       using Teuchos::rcp;
00307       typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type;
00308 
00309       TEST_FOR_EXCEPTION(ortho == "Simple", std::logic_error,
00310        "SimpleOrthoManager does not yet support the "
00311        "MatOrthoManager interface");
00312 
00313       if (ortho == "DGKS") {
00314   int maxNumOrthogPasses;
00315   magnitude_type blkTol, depTol, singTol;
00316   readDgksParameters<Scalar> (params, maxNumOrthogPasses, blkTol, depTol, singTol);
00317   return rcp (new DGKSOrthoManager<Scalar, MV, OP> (label, M, maxNumOrthogPasses, 
00318                 blkTol, depTol, singTol));
00319       }
00320 #ifdef HAVE_BELOS_TSQR
00321       else if (ortho == "TSQR") {
00322   // mfh 12 Jan 2011: TSQR knows how to read its own parameters.
00323   // I didn't want to change the other OrthoManager subclasses'
00324   // public interfaces to accept a parameter list input.
00325   return rcp (new TsqrMatOrthoManager<Scalar, MV, OP> (params, label, M));
00326       }
00327 #endif // HAVE_BELOS_TSQR
00328       else if (ortho == "ICGS") {
00329   int maxNumOrthogPasses;
00330   magnitude_type blkTol, singTol;
00331   readIcgsParameters<Scalar> (params, maxNumOrthogPasses, blkTol, singTol);
00332   return rcp (new ICGSOrthoManager<Scalar, MV, OP>(label, M, maxNumOrthogPasses, 
00333                blkTol, singTol));
00334       }
00335       else if (ortho == "IMGS") {
00336   int maxNumOrthogPasses;
00337   magnitude_type blkTol, singTol;
00338   readImgsParameters<Scalar> (params, maxNumOrthogPasses, blkTol, singTol);
00339   return rcp (new IMGSOrthoManager<Scalar, MV, OP>(label, M, maxNumOrthogPasses,
00340                blkTol, singTol));
00341       }
00342       else {
00343   TEST_FOR_EXCEPTION(true, std::invalid_argument, 
00344          "Invalid orthogonalization manager name: Valid names"
00345          " are " << validNamesString() << ".  For many of "
00346          "the test executables, the orthogonalization manager"
00347          " name often corresponds to the \"ortho\" command-"
00348          "line argument.");
00349       }
00350     }
00351 
00368     Teuchos::RCP<Belos::OrthoManager<Scalar, MV> >
00369     makeOrthoManager (const std::string& ortho, 
00370           const Teuchos::RCP<const OP>& M,
00371           const Teuchos::RCP<OutputManager<Scalar> >& outMan,
00372           const std::string& label,
00373           const Teuchos::RCP<const Teuchos::ParameterList>& params)
00374     {
00375 #ifdef HAVE_BELOS_TSQR
00376       using Belos::TsqrOrthoManager;
00377 #endif // HAVE_BELOS_TSQR
00378       using Teuchos::rcp;
00379 
00380 #ifdef HAVE_BELOS_TSQR
00381       // TsqrMatOrthoManager has to store more things and do more work
00382       // than TsqrOrthoManager, in order for the former to be correct
00383       // for the case of a nondefault (non-Euclidean) inner product.
00384       // Thus, it's better to create a TsqrOrthoManager, when we know
00385       // the operator is the default operator (M is null).  Of course,
00386       // a MatOrthoManager is-an OrthoManager, so returning a
00387       // TsqrMatOrthoManager would still be correct; this is just an
00388       // optimization.
00389       if (ortho == "TSQR" && M.is_null())
00390   return rcp (new TsqrOrthoManager<Scalar, MV> (params, label));
00391 #endif // HAVE_BELOS_TSQR
00392 
00393       if (ortho == "Simple")
00394   {
00395     TEST_FOR_EXCEPTION(! M.is_null(), std::logic_error,
00396            "SimpleOrthoManager is not yet supported "
00397            "when the operator M is nontrivial (i.e., "
00398            "M != null).");
00399     return rcp (new SimpleOrthoManager<Scalar, MV> (outMan, label, params));
00400   }
00401       // A MatOrthoManager is-an OrthoManager.
00402       return makeMatOrthoManager (ortho, M, outMan, label, params);
00403     }
00404   };
00405 
00406 } // namespace Belos
00407 
00408 #endif // __Belos_OrthoManagerFactory_hpp
00409 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines