|
Belos
Version of the Day
|
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
1.7.6.1