|
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 00047 #ifndef BELOS_MATORTHOMANAGER_HPP 00048 #define BELOS_MATORTHOMANAGER_HPP 00049 00065 #include "BelosConfigDefs.hpp" 00066 #include "BelosTypes.hpp" 00067 #include "BelosOrthoManager.hpp" 00068 #include "BelosMultiVecTraits.hpp" 00069 #include "BelosOperatorTraits.hpp" 00070 00071 namespace Belos { 00072 00073 template <class ScalarType, class MV, class OP> 00074 class MatOrthoManager : public OrthoManager<ScalarType,MV> { 00075 protected: 00076 Teuchos::RCP<const OP> _Op; 00077 bool _hasOp; 00078 00079 public: 00081 00082 00083 MatOrthoManager(Teuchos::RCP<const OP> Op = Teuchos::null) : _Op(Op), _hasOp(Op!=Teuchos::null) {}; 00084 00086 virtual ~MatOrthoManager() {}; 00088 00090 00091 00093 void setOp( Teuchos::RCP<const OP> Op ) { 00094 _Op = Op; 00095 _hasOp = (_Op != Teuchos::null); 00096 }; 00097 00099 Teuchos::RCP<const OP> getOp() const { return _Op; } 00100 00102 00103 00105 00106 00111 void innerProd( const MV& X, const MV& Y, 00112 Teuchos::SerialDenseMatrix<int,ScalarType>& Z ) const { 00113 typedef Teuchos::ScalarTraits<ScalarType> SCT; 00114 typedef MultiVecTraits<ScalarType,MV> MVT; 00115 typedef OperatorTraits<ScalarType,MV,OP> OPT; 00116 00117 Teuchos::RCP<const MV> P,Q; 00118 Teuchos::RCP<MV> R; 00119 00120 if (_hasOp) { 00121 // attempt to minimize the amount of work in applying 00122 if ( MVT::GetNumberVecs(X) < MVT::GetNumberVecs(Y) ) { 00123 R = MVT::Clone(X,MVT::GetNumberVecs(X)); 00124 OPT::Apply(*_Op,X,*R); 00125 P = R; 00126 Q = Teuchos::rcp( &Y, false ); 00127 } 00128 else { 00129 P = Teuchos::rcp( &X, false ); 00130 R = MVT::Clone(Y,MVT::GetNumberVecs(Y)); 00131 OPT::Apply(*_Op,Y,*R); 00132 Q = R; 00133 } 00134 } 00135 else { 00136 P = Teuchos::rcp( &X, false ); 00137 Q = Teuchos::rcp( &Y, false ); 00138 } 00139 00140 MVT::MvTransMv(SCT::one(),*P,*Q,Z); 00141 } 00142 00149 void innerProd( const MV& X, const MV& Y, Teuchos::RCP<const MV> MY, 00150 Teuchos::SerialDenseMatrix<int,ScalarType>& Z ) const { 00151 typedef Teuchos::ScalarTraits<ScalarType> SCT; 00152 typedef MultiVecTraits<ScalarType,MV> MVT; 00153 00154 Teuchos::RCP<MV> P,Q; 00155 00156 if ( MY == Teuchos::null ) { 00157 innerProd(X,Y,Z); 00158 } 00159 else if ( _hasOp ) { 00160 // the user has done the matrix vector for us 00161 MVT::MvTransMv(SCT::one(),X,*MY,Z); 00162 } 00163 else { 00164 // there is no matrix vector 00165 MVT::MvTransMv(SCT::one(),X,Y,Z); 00166 } 00167 } 00168 00171 void norm( const MV& X, std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType >& normvec ) const { 00172 norm(X,Teuchos::null,normvec); 00173 } 00174 00192 void 00193 norm (const MV& X, 00194 Teuchos::RCP<const MV> MX, 00195 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& normvec) const 00196 { 00197 typedef Teuchos::ScalarTraits<ScalarType> SCT; 00198 typedef MultiVecTraits<ScalarType,MV> MVT; 00199 typedef OperatorTraits<ScalarType,MV,OP> OPT; 00200 00201 const int numColsX = MVT::GetNumberVecs(X); 00202 if (!_hasOp) { 00203 // X == MX, since the operator M is the identity. 00204 MX = Teuchos::rcp(&X, false); 00205 } 00206 else if (MX.is_null()) { 00207 // The caller didn't give us a previously computed MX, so 00208 // apply the operator. We assign to MX only after applying 00209 // the operator, so that if the application fails, MX won't be 00210 // modified. 00211 Teuchos::RCP<MV> R = MVT::Clone(X, numColsX); 00212 OPT::Apply(*_Op,X,*R); 00213 MX = R; 00214 } 00215 else { 00216 // The caller gave us a previously computed MX. Make sure 00217 // that it has at least as many columns as X. 00218 const int numColsMX = MVT::GetNumberVecs(*MX); 00219 TEUCHOS_TEST_FOR_EXCEPTION(numColsMX < numColsX, std::invalid_argument, 00220 "MatOrthoManager::norm(X, MX, normvec): " 00221 "MX has fewer columns than X: " 00222 "MX has " << numColsMX << " columns, " 00223 "and X has " << numColsX << " columns."); 00224 } 00225 00226 // Make sure that normvec has enough entries to hold the norms 00227 // of all the columns of X. std::vector<T>::size_type is 00228 // unsigned, so do the appropriate cast to avoid signed/unsigned 00229 // comparisons that trigger compiler warnings. 00230 if (normvec.size() < static_cast<size_t>(numColsX)) 00231 normvec.resize (numColsX); 00232 00233 Teuchos::SerialDenseMatrix<int,ScalarType> z(1,1); 00234 Teuchos::RCP<const MV> Xi, MXi; 00235 std::vector<int> ind(1); 00236 for (int i = 0; i < numColsX; ++i) { 00237 ind[0] = i; 00238 Xi = MVT::CloneView(X,ind); 00239 MXi = MVT::CloneView(*MX,ind); 00240 MVT::MvTransMv(SCT::one(),*Xi,*MXi,z); 00241 normvec[i] = SCT::magnitude( SCT::squareroot( z(0,0) ) ); 00242 } 00243 } 00244 00245 00267 virtual void project ( MV &X, Teuchos::RCP<MV> MX, 00268 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C, 00269 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const = 0; 00270 00271 00272 00275 virtual void project ( MV &X, 00276 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C, 00277 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const { 00278 project(X,Teuchos::null,C,Q); 00279 } 00280 00302 virtual int normalize ( MV &X, Teuchos::RCP<MV> MX, 00303 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B ) const = 0; 00304 00305 00308 virtual int normalize ( MV &X, Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B ) const { 00309 return normalize(X,Teuchos::null,B); 00310 } 00311 00312 00313 protected: 00314 virtual int 00315 projectAndNormalizeWithMxImpl (MV &X, 00316 Teuchos::RCP<MV> MX, 00317 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C, 00318 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B, 00319 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const = 0; 00320 00321 virtual int 00322 projectAndNormalizeImpl (MV &X, 00323 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C, 00324 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B, 00325 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00326 { 00327 return this->projectAndNormalizeWithMxImpl (X, Teuchos::null, C, B, Q); 00328 } 00329 00330 public: 00331 00366 int 00367 projectAndNormalize (MV &X, 00368 Teuchos::RCP<MV> MX, 00369 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C, 00370 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B, 00371 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const 00372 { 00373 return this->projectAndNormalizeWithMxImpl (X, MX, C, B, Q); 00374 } 00375 00377 00378 00379 00382 virtual typename Teuchos::ScalarTraits<ScalarType>::magnitudeType 00383 orthonormError(const MV &X) const { 00384 return orthonormError(X,Teuchos::null); 00385 } 00386 00390 virtual typename Teuchos::ScalarTraits<ScalarType>::magnitudeType 00391 orthonormError(const MV &X, Teuchos::RCP<const MV> MX) const = 0; 00392 00395 virtual typename Teuchos::ScalarTraits<ScalarType>::magnitudeType 00396 orthogError(const MV &X1, const MV &X2) const { 00397 return orthogError(X1,Teuchos::null,X2); 00398 } 00399 00404 virtual typename Teuchos::ScalarTraits<ScalarType>::magnitudeType 00405 orthogError(const MV &X1, Teuchos::RCP<const MV> MX1, const MV &X2) const = 0; 00406 00408 00409 }; 00410 00411 } // end of Belos namespace 00412 00413 00414 #endif 00415 00416 // end of file BelosMatOrthoManager.hpp
1.7.6.1