Teko  Version of the Day
 All Classes Files Functions Variables
Teko_Utilities.hpp
Go to the documentation of this file.
00001 /*
00002 // @HEADER
00003 // 
00004 // ***********************************************************************
00005 // 
00006 //      Teko: A package for block and physics based preconditioning
00007 //                  Copyright 2010 Sandia Corporation 
00008 //  
00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00010 // the U.S. Government retains certain rights in this software.
00011 //  
00012 // Redistribution and use in source and binary forms, with or without
00013 // modification, are permitted provided that the following conditions are
00014 // met:
00015 //  
00016 // 1. Redistributions of source code must retain the above copyright
00017 // notice, this list of conditions and the following disclaimer.
00018 //  
00019 // 2. Redistributions in binary form must reproduce the above copyright
00020 // notice, this list of conditions and the following disclaimer in the
00021 // documentation and/or other materials provided with the distribution.
00022 //  
00023 // 3. Neither the name of the Corporation nor the names of the
00024 // contributors may be used to endorse or promote products derived from
00025 // this software without specific prior written permission. 
00026 //  
00027 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00028 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00030 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00031 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00032 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00033 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00034 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00035 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
00036 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00037 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00038 //  
00039 // Questions? Contact Eric C. Cyr (eccyr@sandia.gov)
00040 // 
00041 // ***********************************************************************
00042 // 
00043 // @HEADER
00044 
00045 */
00046 
00055 #ifndef __Teko_Utilities_hpp__
00056 #define __Teko_Utilities_hpp__
00057 
00058 #include "Epetra_CrsMatrix.h"
00059 
00060 // Teuchos includes
00061 #include "Teuchos_VerboseObject.hpp"
00062 
00063 // Thyra includes
00064 #include "Thyra_LinearOpBase.hpp"
00065 #include "Thyra_PhysicallyBlockedLinearOpBase.hpp"
00066 #include "Thyra_ProductVectorSpaceBase.hpp"
00067 #include "Thyra_VectorSpaceBase.hpp"
00068 #include "Thyra_ProductMultiVectorBase.hpp"
00069 #include "Thyra_MultiVectorStdOps.hpp"
00070 #include "Thyra_MultiVectorBase.hpp"
00071 #include "Thyra_VectorBase.hpp"
00072 #include "Thyra_VectorStdOps.hpp"
00073 #include "Thyra_DefaultBlockedLinearOp.hpp"
00074 #include "Thyra_DefaultMultipliedLinearOp.hpp"
00075 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
00076 #include "Thyra_DefaultAddedLinearOp.hpp"
00077 #include "Thyra_DefaultIdentityLinearOp.hpp"
00078 #include "Thyra_DefaultZeroLinearOp.hpp"
00079 
00080 #ifdef _MSC_VER
00081 #ifndef _MSC_EXTENSIONS
00082 #define _MSC_EXTENSIONS
00083 #define TEKO_DEFINED_MSC_EXTENSIONS
00084 #endif
00085 #include <iso646.h> // For C alternative tokens
00086 #endif
00087 
00088 // #define Teko_DEBUG_OFF
00089 #define Teko_DEBUG_INT 5
00090 
00091 namespace Teko {
00092 
00093 using Thyra::multiply;
00094 using Thyra::scale;
00095 using Thyra::add;
00096 using Thyra::identity;
00097 using Thyra::zero; // make it to take one argument (square matrix)
00098 using Thyra::block2x2;
00099 using Thyra::block2x1;
00100 using Thyra::block1x2;
00101 
00120 Teuchos::RCP<Epetra_CrsMatrix> buildGraphLaplacian(int dim,double * coords,const Epetra_CrsMatrix & stencil);
00121 
00144 Teuchos::RCP<Epetra_CrsMatrix> buildGraphLaplacian(double * x,double * y,double * z,int stride,const Epetra_CrsMatrix & stencil);
00145 
00152 const Teuchos::RCP<Teuchos::FancyOStream> getOutputStream();
00153 // inline const Teuchos::RCP<Teuchos::FancyOStream> getOutputStream();
00154 // { return Teuchos::VerboseObjectBase::getDefaultOStream(); }
00155 
00156 #ifndef Teko_DEBUG_OFF
00157    #define Teko_DEBUG_EXPR(str) str
00158    #define Teko_DEBUG_MSG(str,level) if(level<=Teko_DEBUG_INT) { \
00159       Teuchos::RCP<Teuchos::FancyOStream> out = Teko::getOutputStream(); \
00160       *out << "Teko: " << str << std::endl; }
00161    #define Teko_DEBUG_MSG_BEGIN(level) if(level<=Teko_DEBUG_INT) { \
00162       Teko::getOutputStream()->pushTab(3); \
00163       *Teko::getOutputStream() << "Teko: Begin debug MSG\n"; \
00164       std::ostream & DEBUG_STREAM = *Teko::getOutputStream(); \
00165       Teko::getOutputStream()->pushTab(3);
00166    #define Teko_DEBUG_MSG_END() Teko::getOutputStream()->popTab(); \
00167                              *Teko::getOutputStream() << "Teko: End debug MSG\n"; \
00168                               Teko::getOutputStream()->popTab(); }
00169    #define Teko_DEBUG_PUSHTAB() Teko::getOutputStream()->pushTab(3)
00170    #define Teko_DEBUG_POPTAB() Teko::getOutputStream()->popTab()
00171 
00172    struct __DebugScope__ {
00173       __DebugScope__(const std::string & str,int level)
00174          : str_(str), level_(level)
00175       { Teko_DEBUG_MSG("BEGIN "+str_,level_); Teko_DEBUG_PUSHTAB(); }      
00176       ~__DebugScope__()
00177       { Teko_DEBUG_POPTAB(); Teko_DEBUG_MSG("END "+str_,level_); } 
00178       std::string str_; int level_; };
00179    #define Teko_DEBUG_SCOPE(str,level) __DebugScope__ __dbgScope__(str,level);
00180 #else 
00181    #define Teko_DEBUG_EXPR(str)
00182    #define Teko_DEBUG_MSG(str,level)
00183    #define Teko_DEBUG_MSG_BEGIN(level) if(false) { \
00184       std::ostream & DEBUG_STREAM = *Teko::getOutputStream();
00185    #define Teko_DEBUG_MSG_END() }
00186    #define Teko_DEBUG_PUSHTAB() 
00187    #define Teko_DEBUG_POPTAB() 
00188    #define Teko_DEBUG_SCOPE(str,level)
00189 #endif
00190 
00191 // typedefs for increased simplicity
00192 typedef Teuchos::RCP<const Thyra::VectorSpaceBase<double> > VectorSpace;
00193 
00194 // ----------------------------------------------------------------------------
00195 
00197 
00198 
00199 typedef Teuchos::RCP<Thyra::ProductMultiVectorBase<double> > BlockedMultiVector;
00200 typedef Teuchos::RCP<Thyra::MultiVectorBase<double> > MultiVector;
00201 
00203 inline MultiVector toMultiVector(BlockedMultiVector & bmv) { return bmv; }
00204 
00206 inline const MultiVector toMultiVector(const BlockedMultiVector & bmv) { return bmv; }
00207 
00209 inline const BlockedMultiVector toBlockedMultiVector(const MultiVector & bmv) 
00210 { return Teuchos::rcp_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(bmv); }
00211 
00213 inline int blockCount(const BlockedMultiVector & bmv)
00214 { return bmv->productSpace()->numBlocks(); }
00215 
00217 inline MultiVector getBlock(int i,const BlockedMultiVector & bmv)
00218 { return Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(bmv->getMultiVectorBlock(i)); }
00219 
00221 inline MultiVector deepcopy(const MultiVector & v)
00222 { return v->clone_mv(); }
00223 
00225 inline MultiVector copyAndInit(const MultiVector & v,double scalar)
00226 { MultiVector mv = v->clone_mv(); Thyra::assign(mv.ptr(),scalar); return mv; }
00227 
00229 inline BlockedMultiVector deepcopy(const BlockedMultiVector & v)
00230 { return toBlockedMultiVector(v->clone_mv()); }
00231 
00245 inline MultiVector datacopy(const MultiVector & src,MultiVector & dst)
00246 { 
00247    if(dst==Teuchos::null)
00248       return deepcopy(src);
00249 
00250    bool rangeCompat = src->range()->isCompatible(*dst->range());
00251    bool domainCompat = src->domain()->isCompatible(*dst->domain());
00252  
00253    if(not (rangeCompat && domainCompat))
00254       return deepcopy(src);
00255 
00256    // perform data copy
00257    Thyra::assign<double>(dst.ptr(),*src);
00258    return dst;
00259 }
00260 
00274 inline BlockedMultiVector datacopy(const BlockedMultiVector & src,BlockedMultiVector & dst)
00275 { 
00276    if(dst==Teuchos::null)
00277       return deepcopy(src);
00278 
00279    bool rangeCompat = src->range()->isCompatible(*dst->range());
00280    bool domainCompat = src->domain()->isCompatible(*dst->domain());
00281 
00282    if(not (rangeCompat && domainCompat))
00283       return deepcopy(src);
00284 
00285    // perform data copy
00286    Thyra::assign<double>(dst.ptr(),*src);
00287    return dst;
00288 }
00289 
00291 BlockedMultiVector buildBlockedMultiVector(const std::vector<MultiVector> & mvs);
00292 
00303 Teuchos::RCP<Thyra::VectorBase<double> > indicatorVector(
00304                                  const std::vector<int> & indices,
00305                                  const VectorSpace & vs,
00306                                  double onValue=1.0, double offValue=0.0);
00307 
00309 
00310 // ----------------------------------------------------------------------------
00311 
00313 
00314 typedef Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<double> > BlockedLinearOp;
00315 typedef Teuchos::RCP<const Thyra::LinearOpBase<double> > LinearOp;
00316 typedef Teuchos::RCP<Thyra::LinearOpBase<double> > InverseLinearOp;
00317 typedef Teuchos::RCP<Thyra::LinearOpBase<double> > ModifiableLinearOp;
00318 
00320 inline LinearOp zero(const VectorSpace & vs)
00321 { return Thyra::zero<double>(vs,vs); }
00322 
00324 void putScalar(const ModifiableLinearOp & op,double scalar);
00325 
00327 inline VectorSpace rangeSpace(const LinearOp & lo)
00328 { return lo->range(); }
00329 
00331 inline VectorSpace domainSpace(const LinearOp & lo)
00332 { return lo->domain(); }
00333 
00335 inline BlockedLinearOp toBlockedLinearOp(LinearOp & clo)
00336 {
00337    Teuchos::RCP<Thyra::LinearOpBase<double> > lo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(clo);
00338    return Teuchos::rcp_dynamic_cast<Thyra::PhysicallyBlockedLinearOpBase<double> > (lo);
00339 }
00340 
00342 inline const BlockedLinearOp toBlockedLinearOp(const LinearOp & clo)
00343 {
00344    Teuchos::RCP<Thyra::LinearOpBase<double> > lo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(clo);
00345    return Teuchos::rcp_dynamic_cast<Thyra::PhysicallyBlockedLinearOpBase<double> > (lo);
00346 }
00347 
00349 inline LinearOp toLinearOp(BlockedLinearOp & blo) { return blo; }
00350 
00352 inline const LinearOp toLinearOp(const BlockedLinearOp & blo) { return blo; }
00353 
00355 inline LinearOp toLinearOp(ModifiableLinearOp & blo) { return blo; }
00356 
00358 inline const LinearOp toLinearOp(const ModifiableLinearOp & blo) { return blo; }
00359 
00361 inline int blockRowCount(const BlockedLinearOp & blo)
00362 { return blo->productRange()->numBlocks(); }
00363 
00365 inline int blockColCount(const BlockedLinearOp & blo)
00366 { return blo->productDomain()->numBlocks(); }
00367 
00369 inline LinearOp getBlock(int i,int j,const BlockedLinearOp & blo)
00370 { return blo->getBlock(i,j); }
00371 
00373 inline void setBlock(int i,int j,BlockedLinearOp & blo, const LinearOp & lo)
00374 { return blo->setBlock(i,j,lo); }
00375 
00377 inline BlockedLinearOp createBlockedOp()
00378 { return rcp(new Thyra::DefaultBlockedLinearOp<double>()); }
00379 
00391 inline void beginBlockFill(BlockedLinearOp & blo,int rowCnt,int colCnt)
00392 { blo->beginBlockFill(rowCnt,colCnt); }
00393 
00403 inline void beginBlockFill(BlockedLinearOp & blo)
00404 { blo->beginBlockFill(); }
00405 
00407 inline void endBlockFill(BlockedLinearOp & blo)
00408 { blo->endBlockFill(); }
00409 
00411 BlockedLinearOp getUpperTriBlocks(const BlockedLinearOp & blo,bool callEndBlockFill=true);
00412 
00414 BlockedLinearOp getLowerTriBlocks(const BlockedLinearOp & blo,bool callEndBlockFill=true);
00415 
00435 BlockedLinearOp zeroBlockedOp(const BlockedLinearOp & blo);
00436 
00438 bool isZeroOp(const LinearOp op);
00439 
00448 ModifiableLinearOp getAbsRowSumMatrix(const LinearOp & op);
00449 
00458 ModifiableLinearOp getAbsRowSumInvMatrix(const LinearOp & op);
00459 
00467 ModifiableLinearOp getLumpedMatrix(const LinearOp & op);
00468 
00477 ModifiableLinearOp getInvLumpedMatrix(const LinearOp & op);
00478 
00480 
00482 
00483 
00502 void applyOp(const LinearOp & A,const MultiVector & x,MultiVector & y,double alpha=1.0,double beta=0.0);
00503 
00522 inline void applyOp(const LinearOp & A,const BlockedMultiVector & x,BlockedMultiVector & y,double alpha=1.0,double beta=0.0)
00523 { const MultiVector x_mv = toMultiVector(x); MultiVector y_mv = toMultiVector(y);
00524   applyOp(A,x_mv,y_mv,alpha,beta); }
00525 
00535 void update(double alpha,const MultiVector & x,double beta,MultiVector & y);
00536 
00538 inline void update(double alpha,const BlockedMultiVector & x,double beta,BlockedMultiVector & y)
00539 { MultiVector x_mv = toMultiVector(x); MultiVector y_mv = toMultiVector(y);
00540   update(alpha,x_mv,beta,y_mv); }
00541 
00543 inline void scale(const double alpha,MultiVector & x) { Thyra::scale<double>(alpha,x.ptr()); }
00544 
00546 inline void scale(const double alpha,BlockedMultiVector & x) 
00547 {  MultiVector x_mv = toMultiVector(x); scale(alpha,x_mv); }
00548 
00550 inline LinearOp scale(const double alpha,ModifiableLinearOp & a) 
00551 {  return Thyra::nonconstScale(alpha,a); }
00552 
00554 inline LinearOp adjoint(ModifiableLinearOp & a) 
00555 {  return Thyra::nonconstAdjoint(a); }
00556 
00558 
00560 
00561 
00573 const ModifiableLinearOp getDiagonalOp(const LinearOp & op);
00574 
00580 const MultiVector getDiagonal(const LinearOp & op);
00581 
00593 const ModifiableLinearOp getInvDiagonalOp(const LinearOp & op);
00594 
00607 const LinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opm,const LinearOp & opr);
00608 
00623 const ModifiableLinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opm,const LinearOp & opr,
00624                                           const ModifiableLinearOp & destOp);
00625 
00636 const LinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opr);
00637 
00651 const ModifiableLinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opr,
00652                                           const ModifiableLinearOp & destOp);
00653 
00664 const LinearOp explicitAdd(const LinearOp & opl,const LinearOp & opr);
00665 
00678 const ModifiableLinearOp explicitAdd(const LinearOp & opl,const LinearOp & opr,
00679                                      const ModifiableLinearOp & destOp);
00680 
00683 const ModifiableLinearOp explicitSum(const LinearOp & opl,
00684                                      const ModifiableLinearOp & destOp);
00685 
00689 const LinearOp explicitTranspose(const LinearOp & op);
00690 
00694 const LinearOp buildDiagonal(const MultiVector & v,const std::string & lbl="ANYM");
00695 
00699 const LinearOp buildInvDiagonal(const MultiVector & v,const std::string & lbl="ANYM");
00700 
00702 
00726 double computeSpectralRad(const Teuchos::RCP<const Thyra::LinearOpBase<double> > & A,double tol,
00727                           bool isHermitian=false,int numBlocks=5,int restart=0,int verbosity=0);
00728 
00752 double computeSmallestMagEig(const Teuchos::RCP<const Thyra::LinearOpBase<double> > & A, double tol,
00753                           bool isHermitian=false,int numBlocks=5,int restart=0,int verbosity=0);
00754 
00756 typedef enum {  Diagonal     
00757               , Lumped       
00758               , AbsRowSum    
00759         , BlkDiag      
00760               , NotDiag      
00761               } DiagonalType;
00762 
00771 ModifiableLinearOp getDiagonalOp(const Teko::LinearOp & A,const DiagonalType & dt);
00772 
00781 ModifiableLinearOp getInvDiagonalOp(const Teko::LinearOp & A,const DiagonalType & dt);
00782 
00788 const MultiVector getDiagonal(const LinearOp & op,const DiagonalType & dt);
00789 
00796 std::string getDiagonalName(const DiagonalType & dt);
00797 
00806 DiagonalType getDiagonalType(std::string name);
00807 
00808 LinearOp probe(Teuchos::RCP<const Epetra_CrsGraph> &G, const LinearOp & Op);
00809 
00812 double norm_1(const MultiVector & v,std::size_t col);
00813 
00816 double norm_2(const MultiVector & v,std::size_t col);
00817 
00821 void clipLower(MultiVector & v,double lowerBound);
00822 
00826 void clipUpper(MultiVector & v,double upperBound);
00827 
00831 void replaceValue(MultiVector & v,double currentValue,double newValue);
00832 
00835 void columnAverages(const MultiVector & v,std::vector<double> & averages);
00836 
00839 double average(const MultiVector & v);
00840 
00841 } // end namespace Teko
00842 
00843 #ifdef _MSC_VER
00844 #ifdef TEKO_DEFINED_MSC_EXTENSIONS
00845 #undef _MSC_EXTENSIONS
00846 #endif
00847 #endif
00848 
00849 #endif
 All Classes Files Functions Variables