|
Anasazi
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Anasazi: Block Eigensolvers Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00035 #ifndef ANASAZI_SADDLE_OPERATOR_HPP 00036 #define ANASAZI_SADDLE_OPERATOR_HPP 00037 00038 #include "AnasaziConfigDefs.hpp" 00039 #include "AnasaziSaddleContainer.hpp" 00040 #include "AnasaziTraceMinRitzOp.hpp" 00041 00042 #include "Teuchos_SerialDenseSolver.hpp" 00043 00044 using Teuchos::RCP; 00045 00046 enum PrecType {NO_PREC, BD_PREC, UT_PREC}; 00047 00048 namespace Anasazi { 00049 namespace Experimental { 00050 00051 template <class ScalarType, class MV, class OP> 00052 class SaddleOperator : public TraceMinOp<ScalarType,SaddleContainer<ScalarType,MV>,OP> 00053 { 00054 public: 00055 // Default constructor 00056 SaddleOperator( ) { }; 00057 SaddleOperator( const Teuchos::RCP<OP> A, const Teuchos::RCP<const MV> B, PrecType pt=NO_PREC ); 00058 00059 // Applies the saddle point operator to a "multivector" 00060 void Apply(const SaddleContainer<ScalarType,MV>& X, SaddleContainer<ScalarType,MV>& Y) const; 00061 00062 void removeIndices(const std::vector<int>& indicesToRemove) { A_->removeIndices(indicesToRemove); }; 00063 00064 private: 00065 // A is the 1-1 block, and B the 1-2 block 00066 Teuchos::RCP<OP> A_; 00067 Teuchos::RCP<const MV> B_; 00068 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > Schur_; 00069 PrecType pt_; 00070 00071 typedef Anasazi::MultiVecTraits<ScalarType,MV> MVT; 00072 }; 00073 00074 00075 00076 // Default constructor 00077 template <class ScalarType, class MV, class OP> 00078 SaddleOperator<ScalarType, MV, OP>::SaddleOperator( const Teuchos::RCP<OP> A, const Teuchos::RCP<const MV> B, PrecType pt ) 00079 { 00080 // Get a pointer to A and B 00081 A_ = A; 00082 B_ = B; 00083 pt_ = pt; 00084 00085 if(pt == BD_PREC || pt == UT_PREC) 00086 { 00087 // Form the Schur complement 00088 int nvecs = MVT::GetNumberVecs(*B); 00089 Teuchos::RCP<MV> AinvB = MVT::Clone(*B,nvecs); 00090 Schur_ = rcp(new Teuchos::SerialDenseMatrix<int,ScalarType>(nvecs,nvecs)); 00091 00092 A_->Apply(*B_,*AinvB); 00093 00094 MVT::MvTransMv(1., *B_, *AinvB, *Schur_); 00095 } 00096 } 00097 00098 // Applies the saddle point operator to a "multivector" 00099 template <class ScalarType, class MV, class OP> 00100 void SaddleOperator<ScalarType, MV, OP>::Apply(const SaddleContainer<ScalarType,MV>& X, SaddleContainer<ScalarType,MV>& Y) const 00101 { 00102 if(pt_ == NO_PREC) 00103 { 00104 // trans does literally nothing, because the operator is symmetric 00105 // Y.bottom = B'X.top 00106 MVT::MvTransMv(1., *B_, *(X.X_), *Y.Y_); 00107 00108 // Y.top = A*X.top+B*X.bottom 00109 A_->Apply(*(X.X_), *(Y.X_)); 00110 MVT::MvTimesMatAddMv(1., *B_, *X.Y_, 1., *(Y.X_)); 00111 } 00112 else if(pt_ == BD_PREC) 00113 { 00114 Teuchos::SerialDenseSolver<int,ScalarType> MySolver; 00115 00116 // Solve A Y.X = X.X 00117 A_->Apply(*(X.X_),*(Y.X_)); 00118 00119 // So, let me tell you a funny story about how the SerialDenseSolver destroys the original matrix... 00120 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > localSchur = Teuchos::rcp(new Teuchos::SerialDenseMatrix<int,ScalarType>(*Schur_)); 00121 00122 // Solve the small system 00123 MySolver.setMatrix(localSchur); 00124 MySolver.setVectors(Y.Y_, X.Y_); 00125 MySolver.solve(); 00126 } 00127 else if(pt_ == UT_PREC) 00128 { 00129 std::cout << "block upper triangular preconditioning is not implemented yet. Sorry for any inconvenience!\n"; 00130 } 00131 else 00132 { 00133 std::cout << "Not a valid preconditioner type\n"; 00134 } 00135 } 00136 00137 } // End namespace Experimental 00138 00139 template<class ScalarType, class MV, class OP> 00140 class OperatorTraits<ScalarType, Experimental::SaddleContainer<ScalarType,MV>, Experimental::SaddleOperator<ScalarType,MV,OP> > 00141 { 00142 public: 00143 static void Apply( const Experimental::SaddleOperator<ScalarType,MV,OP>& Op, 00144 const Experimental::SaddleContainer<ScalarType,MV>& x, 00145 Experimental::SaddleContainer<ScalarType,MV>& y) 00146 { Op.Apply( x, y); }; 00147 }; 00148 00149 } // end namespace Anasazi 00150 00151 #endif
1.7.6.1