|
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 00313 if (ortho == "DGKS") { 00314 typedef DGKSOrthoManager<Scalar, MV, OP> dgks_type; 00315 return rcp (new dgks_type (params, label, M)); 00316 } 00317 #ifdef HAVE_BELOS_TSQR 00318 else if (ortho == "TSQR") { 00319 typedef TsqrMatOrthoManager<Scalar, MV, OP> ortho_type; 00320 return rcp (new ortho_type (params, label, M)); 00321 } 00322 #endif // HAVE_BELOS_TSQR 00323 else if (ortho == "ICGS") { 00324 typedef ICGSOrthoManager<Scalar, MV, OP> ortho_type; 00325 return rcp (new ortho_type (params, label, M)); 00326 } 00327 else if (ortho == "IMGS") { 00328 typedef IMGSOrthoManager<Scalar, MV, OP> ortho_type; 00329 return rcp (new ortho_type (params, label, M)); 00330 } 00331 else if (ortho == "Simple") { 00332 TEUCHOS_TEST_FOR_EXCEPTION(ortho == "Simple", std::logic_error, 00333 "SimpleOrthoManager does not yet support " 00334 "the MatOrthoManager interface"); 00335 } 00336 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 00337 "Invalid orthogonalization manager name: Valid names" 00338 " are " << validNamesString() << ". For many of " 00339 "the test executables, the orthogonalization manager" 00340 " name often corresponds to the \"ortho\" command-" 00341 "line argument."); 00342 return Teuchos::null; // Guard to avoid compiler warnings. 00343 } 00344 00361 Teuchos::RCP<Belos::OrthoManager<Scalar, MV> > 00362 makeOrthoManager (const std::string& ortho, 00363 const Teuchos::RCP<const OP>& M, 00364 const Teuchos::RCP<OutputManager<Scalar> >& outMan, 00365 const std::string& label, 00366 const Teuchos::RCP<Teuchos::ParameterList>& params) 00367 { 00368 #ifdef HAVE_BELOS_TSQR 00369 using Belos::TsqrOrthoManager; 00370 #endif // HAVE_BELOS_TSQR 00371 using Teuchos::rcp; 00372 00373 if (ortho == "Simple") { 00374 TEUCHOS_TEST_FOR_EXCEPTION(! M.is_null(), std::logic_error, 00375 "SimpleOrthoManager is not yet supported " 00376 "when the operator M is nontrivial (i.e., " 00377 "M != null)."); 00378 return rcp (new SimpleOrthoManager<Scalar, MV> (outMan, label, params)); 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 else if (ortho == "TSQR" && M.is_null()) { 00390 return rcp (new TsqrOrthoManager<Scalar, MV> (params, label)); 00391 } 00392 #endif // HAVE_BELOS_TSQR 00393 else { 00394 // A MatOrthoManager is-an OrthoManager. 00395 return makeMatOrthoManager (ortho, M, outMan, label, params); 00396 } 00397 } 00398 }; 00399 00400 } // namespace Belos 00401 00402 #endif // __Belos_OrthoManagerFactory_hpp 00403
1.7.6.1