|
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 00044 00045 #ifndef __BelosTsqrOrthoManager_hpp 00046 #define __BelosTsqrOrthoManager_hpp 00047 00048 #include "BelosTsqrOrthoManagerImpl.hpp" 00049 // Belos doesn't have an SVQB orthomanager implemented yet, so we just 00050 // use a default orthomanager for the case where the inner product 00051 // matrix is nontrivial. 00052 #include "BelosDGKSOrthoManager.hpp" 00053 00054 00055 namespace Belos { 00056 00078 template<class Scalar, class MV> 00079 class OutOfPlaceNormalizerMixin { 00080 public: 00081 typedef Scalar scalar_type; 00082 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type; 00085 typedef MV multivector_type; 00086 00087 typedef Teuchos::SerialDenseMatrix<int, Scalar> mat_type; 00088 typedef Teuchos::RCP<mat_type> mat_ptr; 00089 00098 virtual int 00099 normalizeOutOfPlace (MV& X, MV& Q, mat_ptr B) const = 0; 00100 00119 virtual int 00120 projectAndNormalizeOutOfPlace (MV& X_in, 00121 MV& X_out, 00122 Teuchos::Array<mat_ptr> C, 00123 mat_ptr B, 00124 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const = 0; 00125 00127 virtual ~OutOfPlaceNormalizerMixin () {} 00128 }; 00129 00136 template<class Scalar, class MV> 00137 class TsqrOrthoManager : 00138 public OrthoManager<Scalar, MV>, 00139 public OutOfPlaceNormalizerMixin<Scalar, MV>, 00140 public Teuchos::ParameterListAcceptor 00141 { 00142 public: 00143 typedef Scalar scalar_type; 00144 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type; 00146 typedef MV multivector_type; 00147 00148 typedef Teuchos::SerialDenseMatrix<int, Scalar> mat_type; 00149 typedef Teuchos::RCP<mat_type> mat_ptr; 00150 00151 void setParameterList (const Teuchos::RCP<Teuchos::ParameterList>& params) { 00152 impl_.setParameterList (params); 00153 } 00154 00155 Teuchos::RCP<Teuchos::ParameterList> getNonconstParameterList () { 00156 return impl_.getNonconstParameterList (); 00157 } 00158 00159 Teuchos::RCP<Teuchos::ParameterList> unsetParameterList () { 00160 return impl_.unsetParameterList (); 00161 } 00162 00170 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const { 00171 return impl_.getValidParameters(); 00172 } 00173 00183 Teuchos::RCP<const Teuchos::ParameterList> getFastParameters() const { 00184 return impl_.getFastParameters(); 00185 } 00186 00202 TsqrOrthoManager (const Teuchos::RCP<Teuchos::ParameterList>& params, 00203 const std::string& label = "Belos") : 00204 impl_ (params, label) 00205 {} 00206 00211 TsqrOrthoManager (const std::string& label) : 00212 impl_ (label) 00213 {} 00214 00216 virtual ~TsqrOrthoManager() {} 00217 00239 void 00240 setReorthogonalizationCallback (const Teuchos::RCP<ReorthogonalizationCallback<Scalar> >& callback) 00241 { 00242 impl_.setReorthogonalizationCallback (callback); 00243 } 00244 00245 void innerProd (const MV &X, const MV &Y, mat_type& Z) const { 00246 return impl_.innerProd (X, Y, Z); 00247 } 00248 00249 void norm (const MV& X, std::vector<magnitude_type>& normVec) const { 00250 return impl_.norm (X, normVec); 00251 } 00252 00253 void 00254 project (MV &X, 00255 Teuchos::Array<mat_ptr> C, 00256 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00257 { 00258 return impl_.project (X, C, Q); 00259 } 00260 00261 int 00262 normalize (MV &X, mat_ptr B) const 00263 { 00264 return impl_.normalize (X, B); 00265 } 00266 00267 protected: 00268 virtual int 00269 projectAndNormalizeImpl (MV &X, 00270 Teuchos::Array<mat_ptr> C, 00271 mat_ptr B, 00272 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00273 { 00274 return impl_.projectAndNormalize (X, C, B, Q); 00275 } 00276 00277 public: 00294 int 00295 normalizeOutOfPlace (MV& X, MV& Q, mat_ptr B) const 00296 { 00297 return impl_.normalizeOutOfPlace (X, Q, B); 00298 } 00299 00320 int 00321 projectAndNormalizeOutOfPlace (MV& X_in, 00322 MV& X_out, 00323 Teuchos::Array<mat_ptr> C, 00324 mat_ptr B, 00325 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00326 { 00327 return impl_.projectAndNormalizeOutOfPlace (X_in, X_out, C, B, Q); 00328 } 00329 00330 magnitude_type orthonormError (const MV &X) const { 00331 return impl_.orthonormError (X); 00332 } 00333 00334 magnitude_type orthogError (const MV &X1, const MV &X2) const { 00335 return impl_.orthogError (X1, X2); 00336 } 00337 00345 void setLabel (const std::string& label) { 00346 impl_.setLabel (label); 00347 } 00348 00349 const std::string& getLabel() const { return impl_.getLabel(); } 00350 00351 private: 00357 mutable TsqrOrthoManagerImpl<Scalar, MV> impl_; 00358 00360 std::string label_; 00361 }; 00362 00363 00377 template<class Scalar, class MV, class OP> 00378 class TsqrMatOrthoManager : 00379 public MatOrthoManager<Scalar, MV, OP>, 00380 public OutOfPlaceNormalizerMixin<Scalar, MV>, 00381 public Teuchos::ParameterListAcceptorDefaultBase 00382 { 00383 public: 00384 typedef Scalar scalar_type; 00385 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type; 00387 typedef MV multivector_type; 00389 typedef OP operator_type; 00390 00391 typedef Teuchos::SerialDenseMatrix<int, Scalar> mat_type; 00392 typedef Teuchos::RCP<mat_type> mat_ptr; 00393 00394 private: 00403 typedef MatOrthoManager<Scalar, MV, OP> base_type; 00404 00407 typedef TsqrOrthoManagerImpl<Scalar, MV> tsqr_type; 00408 00411 typedef DGKSOrthoManager<Scalar, MV, OP> dgks_type; 00412 00415 typedef MultiVecTraits<Scalar, MV> MVT; 00416 00417 public: 00438 TsqrMatOrthoManager (const Teuchos::RCP<Teuchos::ParameterList>& params, 00439 const std::string& label = "Belos", 00440 Teuchos::RCP<const OP> Op = Teuchos::null) : 00441 MatOrthoManager<Scalar, MV, OP> (Op), 00442 tsqr_ (params, label), 00443 pDgks_ (Teuchos::null) // Initialized lazily 00444 {} 00445 00454 TsqrMatOrthoManager (const std::string& label = "Belos", 00455 Teuchos::RCP<const OP> Op = Teuchos::null) : 00456 MatOrthoManager<Scalar, MV, OP> (Op), 00457 tsqr_ (label), 00458 pDgks_ (Teuchos::null) // Initialized lazily 00459 {} 00460 00462 virtual ~TsqrMatOrthoManager() {} 00463 00471 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const { 00472 return tsqr_.getValidParameters (); 00473 } 00474 00484 Teuchos::RCP<const Teuchos::ParameterList> getFastParameters() { 00485 return tsqr_.getFastParameters (); 00486 } 00487 00488 void setParameterList (const Teuchos::RCP<Teuchos::ParameterList>& params) { 00489 tsqr_.setParameterList (params); 00490 } 00491 00492 const std::string& getLabel() const { return tsqr_.getLabel (); } 00493 00494 void 00495 setOp (Teuchos::RCP<const OP> Op) 00496 { 00497 // We override the base class' setOp() so that the 00498 // DGKSOrthoManager instance gets the new op. 00499 // 00500 // The base_type notation helps C++ resolve the name for a 00501 // member function of a templated base class. 00502 base_type::setOp (Op); // base class gets a copy of the Op too 00503 00504 if (! Op.is_null()) { 00505 ensureDgksInit (); // Make sure the DGKS object has been initialized 00506 pDgks_->setOp (Op); 00507 } 00508 } 00509 00510 Teuchos::RCP<const OP> getOp () const { 00511 // The base_type notation helps C++ resolve the name for a 00512 // member function of a templated base class. 00513 return base_type::getOp(); 00514 } 00515 00516 void 00517 project (MV &X, 00518 Teuchos::RCP<MV> MX, 00519 Teuchos::Array<mat_ptr> C, 00520 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00521 { 00522 if (getOp().is_null()) { 00523 tsqr_.project (X, C, Q); 00524 if (! MX.is_null()) { 00525 // MX gets a copy of X; M is the identity operator. 00526 MVT::Assign (X, *MX); 00527 } 00528 } else { 00529 ensureDgksInit (); 00530 pDgks_->project (X, MX, C, Q); 00531 } 00532 } 00533 00534 void 00535 project (MV &X, 00536 Teuchos::Array<mat_ptr> C, 00537 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00538 { 00539 project (X, Teuchos::null, C, Q); 00540 } 00541 00542 int 00543 normalize (MV& X, Teuchos::RCP<MV> MX, mat_ptr B) const 00544 { 00545 if (getOp().is_null()) { 00546 const int rank = tsqr_.normalize (X, B); 00547 if (! MX.is_null()) { 00548 // MX gets a copy of X; M is the identity operator. 00549 MVT::Assign (X, *MX); 00550 } 00551 return rank; 00552 } else { 00553 ensureDgksInit (); 00554 return pDgks_->normalize (X, MX, B); 00555 } 00556 } 00557 00558 int normalize (MV& X, mat_ptr B) const { 00559 return normalize (X, Teuchos::null, B); 00560 } 00561 00562 // Attempted fix for a warning about hiding 00563 // OrthoManager::projectAndNormalize(). Unfortunately, this fix turns out 00564 // to produce a compilation error with cray++, see bug #6129, 00565 // <https://software.sandia.gov/bugzilla/show_bug.cgi?id=6129>. 00566 //using Belos::OrthoManager<Scalar, MV>::projectAndNormalize; 00567 00568 protected: 00569 virtual int 00570 projectAndNormalizeWithMxImpl (MV &X, 00571 Teuchos::RCP<MV> MX, 00572 Teuchos::Array<mat_ptr> C, 00573 mat_ptr B, 00574 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00575 { 00576 if (getOp().is_null()) { 00577 const int rank = tsqr_.projectAndNormalize (X, C, B, Q); 00578 if (! MX.is_null()) { 00579 // MX gets a copy of X; M is the identity operator. 00580 MVT::Assign (X, *MX); 00581 } 00582 return rank; 00583 } else { 00584 ensureDgksInit (); 00585 return pDgks_->projectAndNormalize (X, MX, C, B, Q); 00586 } 00587 } 00588 00589 public: 00590 int 00591 normalizeOutOfPlace (MV& X, MV& Q, mat_ptr B) const 00592 { 00593 if (getOp().is_null()) { 00594 return tsqr_.normalizeOutOfPlace (X, Q, B); 00595 } else { 00596 // DGKS normalizes in place, so we have to copy. 00597 ensureDgksInit (); 00598 const int rank = pDgks_->normalize (X, B); 00599 MVT::Assign (X, Q); 00600 return rank; 00601 } 00602 } 00603 00604 int 00605 projectAndNormalizeOutOfPlace (MV& X_in, 00606 MV& X_out, 00607 Teuchos::Array<mat_ptr> C, 00608 mat_ptr B, 00609 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00610 { 00611 using Teuchos::null; 00612 00613 if (getOp().is_null()) { 00614 return tsqr_.projectAndNormalizeOutOfPlace (X_in, X_out, C, B, Q); 00615 } else { 00616 // DGKS normalizes in place, so we have to copy. 00617 ensureDgksInit (); 00618 const int rank = pDgks_->projectAndNormalize (X_in, null, C, B, Q); 00619 MVT::Assign (X_in, X_out); 00620 return rank; 00621 } 00622 } 00623 00624 magnitude_type 00625 orthonormError (const MV &X, Teuchos::RCP<const MV> MX) const 00626 { 00627 if (getOp().is_null()) { 00628 return tsqr_.orthonormError (X); // Ignore MX 00629 } else { 00630 ensureDgksInit (); 00631 return pDgks_->orthonormError (X, MX); 00632 } 00633 } 00634 00635 magnitude_type orthonormError (const MV &X) const { 00636 return orthonormError (X, Teuchos::null); 00637 } 00638 00639 magnitude_type orthogError (const MV &X1, const MV &X2) const { 00640 return orthogError (X1, Teuchos::null, X2); 00641 } 00642 00643 magnitude_type 00644 orthogError (const MV &X1, 00645 Teuchos::RCP<const MV> MX1, 00646 const MV &X2) const 00647 { 00648 if (getOp ().is_null ()) { 00649 // Ignore MX1, since we don't need to write to it. 00650 return tsqr_.orthogError (X1, X2); 00651 } else { 00652 ensureDgksInit (); 00653 return pDgks_->orthogError (X1, MX1, X2); 00654 } 00655 } 00656 00657 void 00658 setLabel (const std::string& label) 00659 { 00660 tsqr_.setLabel (label); 00661 00662 // Make sure DGKS gets the new label, if it's initialized. 00663 // Otherwise, it will get the new label on initialization. 00664 if (! pDgks_.is_null ()) { 00665 pDgks_->setLabel (label); 00666 } 00667 } 00668 00669 private: 00671 void 00672 ensureDgksInit () const 00673 { 00674 // NOTE (mfh 11 Jan 2011) DGKS has a parameter that needs to be 00675 // set. For now, we just use the default value of the parameter. 00676 if (pDgks_.is_null ()) { 00677 pDgks_ = Teuchos::rcp (new dgks_type (getLabel (), getOp ())); 00678 } 00679 } 00680 00688 mutable tsqr_type tsqr_; 00689 00695 mutable Teuchos::RCP<dgks_type> pDgks_; 00696 }; 00697 00698 } // namespace Belos 00699 00700 #endif // __BelosTsqrOrthoManager_hpp
1.7.6.1