00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00055 #ifndef __Teko_Utilities_hpp__
00056 #define __Teko_Utilities_hpp__
00057
00058 #include "Epetra_CrsMatrix.h"
00059
00060
00061 #include "Teuchos_VerboseObject.hpp"
00062
00063
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>
00086 #endif
00087
00088
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;
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
00154
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
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
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
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 }
00842
00843 #ifdef _MSC_VER
00844 #ifdef TEKO_DEFINED_MSC_EXTENSIONS
00845 #undef _MSC_EXTENSIONS
00846 #endif
00847 #endif
00848
00849 #endif