55 #ifndef __Teko_Utilities_hpp__
56 #define __Teko_Utilities_hpp__
58 #include "Epetra_CrsMatrix.h"
59 #include "Tpetra_CrsMatrix.hpp"
62 #include "Teuchos_VerboseObject.hpp"
65 #include "Thyra_LinearOpBase.hpp"
66 #include "Thyra_PhysicallyBlockedLinearOpBase.hpp"
67 #include "Thyra_ProductVectorSpaceBase.hpp"
68 #include "Thyra_VectorSpaceBase.hpp"
69 #include "Thyra_ProductMultiVectorBase.hpp"
70 #include "Thyra_MultiVectorStdOps.hpp"
71 #include "Thyra_MultiVectorBase.hpp"
72 #include "Thyra_VectorBase.hpp"
73 #include "Thyra_VectorStdOps.hpp"
74 #include "Thyra_DefaultBlockedLinearOp.hpp"
75 #include "Thyra_DefaultMultipliedLinearOp.hpp"
76 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
77 #include "Thyra_DefaultAddedLinearOp.hpp"
78 #include "Thyra_DefaultIdentityLinearOp.hpp"
79 #include "Thyra_DefaultZeroLinearOp.hpp"
81 #include "Teko_ConfigDefs.hpp"
84 #ifndef _MSC_EXTENSIONS
85 #define _MSC_EXTENSIONS
86 #define TEKO_DEFINED_MSC_EXTENSIONS
92 #define Teko_DEBUG_INT 5
96 using Thyra::multiply;
99 using Thyra::identity;
101 using Thyra::block2x2;
102 using Thyra::block2x1;
103 using Thyra::block1x2;
123 Teuchos::RCP<Epetra_CrsMatrix> buildGraphLaplacian(
int dim,
double * coords,
const Epetra_CrsMatrix & stencil);
124 Teuchos::RCP<Tpetra::CrsMatrix<ST,LO,GO,NT> > buildGraphLaplacian(
int dim,ST * coords,
const Tpetra::CrsMatrix<ST,LO,GO,NT> & stencil);
148 Teuchos::RCP<Epetra_CrsMatrix> buildGraphLaplacian(
double * x,
double * y,
double * z,
int stride,
const Epetra_CrsMatrix & stencil);
149 Teuchos::RCP<Tpetra::CrsMatrix<ST,LO,GO,NT> > buildGraphLaplacian(ST * x,ST * y,ST * z,GO stride,
const Tpetra::CrsMatrix<ST,LO,GO,NT> & stencil);
157 const Teuchos::RCP<Teuchos::FancyOStream> getOutputStream();
161 #ifndef Teko_DEBUG_OFF
163 #define Teko_DEBUG_EXPR(str) str
164 #define Teko_DEBUG_MSG(str,level) if(level<=Teko_DEBUG_INT) { \
165 Teuchos::RCP<Teuchos::FancyOStream> out = Teko::getOutputStream(); \
166 *out << "Teko: " << str << std::endl; }
167 #define Teko_DEBUG_MSG_BEGIN(level) if(level<=Teko_DEBUG_INT) { \
168 Teko::getOutputStream()->pushTab(3); \
169 *Teko::getOutputStream() << "Teko: Begin debug MSG\n"; \
170 std::ostream & DEBUG_STREAM = *Teko::getOutputStream(); \
171 Teko::getOutputStream()->pushTab(3);
172 #define Teko_DEBUG_MSG_END() Teko::getOutputStream()->popTab(); \
173 *Teko::getOutputStream() << "Teko: End debug MSG\n"; \
174 Teko::getOutputStream()->popTab(); }
175 #define Teko_DEBUG_PUSHTAB() Teko::getOutputStream()->pushTab(3)
176 #define Teko_DEBUG_POPTAB() Teko::getOutputStream()->popTab()
177 #define Teko_DEBUG_SCOPE(str,level)
188 #define Teko_DEBUG_EXPR(str)
189 #define Teko_DEBUG_MSG(str,level)
190 #define Teko_DEBUG_MSG_BEGIN(level) if(false) { \
191 std::ostream & DEBUG_STREAM = *Teko::getOutputStream();
192 #define Teko_DEBUG_MSG_END() }
193 #define Teko_DEBUG_PUSHTAB()
194 #define Teko_DEBUG_POPTAB()
195 #define Teko_DEBUG_SCOPE(str,level)
199 typedef Teuchos::RCP<const Thyra::VectorSpaceBase<double> > VectorSpace;
206 typedef Teuchos::RCP<Thyra::ProductMultiVectorBase<double> > BlockedMultiVector;
207 typedef Teuchos::RCP<Thyra::MultiVectorBase<double> > MultiVector;
210 inline MultiVector toMultiVector(BlockedMultiVector & bmv) {
return bmv; }
213 inline const MultiVector toMultiVector(
const BlockedMultiVector & bmv) {
return bmv; }
216 inline const BlockedMultiVector toBlockedMultiVector(
const MultiVector & bmv)
217 {
return Teuchos::rcp_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(bmv); }
220 inline int blockCount(
const BlockedMultiVector & bmv)
221 {
return bmv->productSpace()->numBlocks(); }
224 inline MultiVector getBlock(
int i,
const BlockedMultiVector & bmv)
225 {
return Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(bmv->getMultiVectorBlock(i)); }
228 inline MultiVector deepcopy(
const MultiVector & v)
229 {
return v->clone_mv(); }
232 inline MultiVector copyAndInit(
const MultiVector & v,
double scalar)
233 { MultiVector mv = v->clone_mv(); Thyra::assign(mv.ptr(),scalar);
return mv; }
236 inline BlockedMultiVector deepcopy(
const BlockedMultiVector & v)
237 {
return toBlockedMultiVector(v->clone_mv()); }
252 inline MultiVector datacopy(
const MultiVector & src,MultiVector & dst)
254 if(dst==Teuchos::null)
255 return deepcopy(src);
257 bool rangeCompat = src->range()->isCompatible(*dst->range());
258 bool domainCompat = src->domain()->isCompatible(*dst->domain());
260 if(not (rangeCompat && domainCompat))
261 return deepcopy(src);
264 Thyra::assign<double>(dst.ptr(),*src);
281 inline BlockedMultiVector datacopy(
const BlockedMultiVector & src,BlockedMultiVector & dst)
283 if(dst==Teuchos::null)
284 return deepcopy(src);
286 bool rangeCompat = src->range()->isCompatible(*dst->range());
287 bool domainCompat = src->domain()->isCompatible(*dst->domain());
289 if(not (rangeCompat && domainCompat))
290 return deepcopy(src);
293 Thyra::assign<double>(dst.ptr(),*src);
298 BlockedMultiVector buildBlockedMultiVector(
const std::vector<MultiVector> & mvs);
310 Teuchos::RCP<Thyra::VectorBase<double> > indicatorVector(
311 const std::vector<int> & indices,
312 const VectorSpace & vs,
313 double onValue=1.0,
double offValue=0.0);
321 typedef Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<ST> > BlockedLinearOp;
322 typedef Teuchos::RCP<const Thyra::LinearOpBase<ST> > LinearOp;
323 typedef Teuchos::RCP<Thyra::LinearOpBase<ST> > InverseLinearOp;
324 typedef Teuchos::RCP<Thyra::LinearOpBase<ST> > ModifiableLinearOp;
327 inline LinearOp zero(
const VectorSpace & vs)
328 {
return Thyra::zero<ST>(vs,vs); }
331 void putScalar(
const ModifiableLinearOp & op,
double scalar);
334 inline VectorSpace rangeSpace(
const LinearOp & lo)
335 {
return lo->range(); }
338 inline VectorSpace domainSpace(
const LinearOp & lo)
339 {
return lo->domain(); }
342 inline BlockedLinearOp toBlockedLinearOp(LinearOp & clo)
344 Teuchos::RCP<Thyra::LinearOpBase<double> > lo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(clo);
345 return Teuchos::rcp_dynamic_cast<Thyra::PhysicallyBlockedLinearOpBase<double> > (lo);
349 inline const BlockedLinearOp toBlockedLinearOp(
const LinearOp & clo)
351 Teuchos::RCP<Thyra::LinearOpBase<double> > lo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(clo);
352 return Teuchos::rcp_dynamic_cast<Thyra::PhysicallyBlockedLinearOpBase<double> > (lo);
356 inline LinearOp toLinearOp(BlockedLinearOp & blo) {
return blo; }
359 inline const LinearOp toLinearOp(
const BlockedLinearOp & blo) {
return blo; }
362 inline LinearOp toLinearOp(ModifiableLinearOp & blo) {
return blo; }
365 inline const LinearOp toLinearOp(
const ModifiableLinearOp & blo) {
return blo; }
368 inline int blockRowCount(
const BlockedLinearOp & blo)
369 {
return blo->productRange()->numBlocks(); }
372 inline int blockColCount(
const BlockedLinearOp & blo)
373 {
return blo->productDomain()->numBlocks(); }
376 inline LinearOp getBlock(
int i,
int j,
const BlockedLinearOp & blo)
377 {
return blo->getBlock(i,j); }
380 inline void setBlock(
int i,
int j,BlockedLinearOp & blo,
const LinearOp & lo)
381 {
return blo->setBlock(i,j,lo); }
384 inline BlockedLinearOp createBlockedOp()
385 {
return rcp(
new Thyra::DefaultBlockedLinearOp<double>()); }
398 inline void beginBlockFill(BlockedLinearOp & blo,
int rowCnt,
int colCnt)
399 { blo->beginBlockFill(rowCnt,colCnt); }
410 inline void beginBlockFill(BlockedLinearOp & blo)
411 { blo->beginBlockFill(); }
414 inline void endBlockFill(BlockedLinearOp & blo)
415 { blo->endBlockFill(); }
418 BlockedLinearOp getUpperTriBlocks(
const BlockedLinearOp & blo,
bool callEndBlockFill=
true);
421 BlockedLinearOp getLowerTriBlocks(
const BlockedLinearOp & blo,
bool callEndBlockFill=
true);
442 BlockedLinearOp zeroBlockedOp(
const BlockedLinearOp & blo);
445 bool isZeroOp(
const LinearOp op);
455 ModifiableLinearOp getAbsRowSumMatrix(
const LinearOp & op);
465 ModifiableLinearOp getAbsRowSumInvMatrix(
const LinearOp & op);
474 ModifiableLinearOp getLumpedMatrix(
const LinearOp & op);
484 ModifiableLinearOp getInvLumpedMatrix(
const LinearOp & op);
509 void applyOp(
const LinearOp & A,
const MultiVector & x,MultiVector & y,
double alpha=1.0,
double beta=0.0);
530 void applyTransposeOp(
const LinearOp & A,
const MultiVector & x,MultiVector & y,
double alpha=1.0,
double beta=0.0);
550 inline void applyOp(
const LinearOp & A,
const BlockedMultiVector & x,BlockedMultiVector & y,
double alpha=1.0,
double beta=0.0)
551 {
const MultiVector x_mv = toMultiVector(x); MultiVector y_mv = toMultiVector(y);
552 applyOp(A,x_mv,y_mv,alpha,beta); }
572 inline void applyTransposeOp(
const LinearOp & A,
const BlockedMultiVector & x,BlockedMultiVector & y,
double alpha=1.0,
double beta=0.0)
573 {
const MultiVector x_mv = toMultiVector(x); MultiVector y_mv = toMultiVector(y);
574 applyTransposeOp(A,x_mv,y_mv,alpha,beta); }
585 void update(
double alpha,
const MultiVector & x,
double beta,MultiVector & y);
588 inline void update(
double alpha,
const BlockedMultiVector & x,
double beta,BlockedMultiVector & y)
589 { MultiVector x_mv = toMultiVector(x); MultiVector y_mv = toMultiVector(y);
590 update(alpha,x_mv,beta,y_mv); }
593 inline void scale(
const double alpha,MultiVector & x) { Thyra::scale<double>(alpha,x.ptr()); }
596 inline void scale(
const double alpha,BlockedMultiVector & x)
597 { MultiVector x_mv = toMultiVector(x); scale(alpha,x_mv); }
600 inline LinearOp scale(
const double alpha,ModifiableLinearOp & a)
601 {
return Thyra::nonconstScale(alpha,a); }
604 inline LinearOp adjoint(ModifiableLinearOp & a)
605 {
return Thyra::nonconstAdjoint(a); }
623 const ModifiableLinearOp getDiagonalOp(
const LinearOp & op);
630 const MultiVector getDiagonal(
const LinearOp & op);
643 const ModifiableLinearOp getInvDiagonalOp(
const LinearOp & op);
657 const LinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opm,
const LinearOp & opr);
673 const ModifiableLinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opm,
const LinearOp & opr,
674 const ModifiableLinearOp & destOp);
686 const LinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opr);
701 const ModifiableLinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opr,
702 const ModifiableLinearOp & destOp);
714 const LinearOp explicitAdd(
const LinearOp & opl,
const LinearOp & opr);
728 const ModifiableLinearOp explicitAdd(
const LinearOp & opl,
const LinearOp & opr,
729 const ModifiableLinearOp & destOp);
733 const ModifiableLinearOp explicitSum(
const LinearOp & opl,
734 const ModifiableLinearOp & destOp);
739 const LinearOp explicitTranspose(
const LinearOp & op);
743 double frobeniusNorm(
const LinearOp & op);
744 double oneNorm(
const LinearOp & op);
745 double infNorm(
const LinearOp & op);
750 const LinearOp buildDiagonal(
const MultiVector & v,
const std::string & lbl=
"ANYM");
755 const LinearOp buildInvDiagonal(
const MultiVector & v,
const std::string & lbl=
"ANYM");
782 double computeSpectralRad(
const Teuchos::RCP<
const Thyra::LinearOpBase<double> > & A,
double tol,
783 bool isHermitian=
false,
int numBlocks=5,
int restart=0,
int verbosity=0);
808 double computeSmallestMagEig(
const Teuchos::RCP<
const Thyra::LinearOpBase<double> > & A,
double tol,
809 bool isHermitian=
false,
int numBlocks=5,
int restart=0,
int verbosity=0);
812 typedef enum { Diagonal
827 ModifiableLinearOp getDiagonalOp(
const Teko::LinearOp & A,
const DiagonalType & dt);
837 ModifiableLinearOp getInvDiagonalOp(
const Teko::LinearOp & A,
const DiagonalType & dt);
844 const MultiVector getDiagonal(
const LinearOp & op,
const DiagonalType & dt);
852 std::string getDiagonalName(
const DiagonalType & dt);
862 DiagonalType getDiagonalType(std::string name);
864 LinearOp probe(Teuchos::RCP<const Epetra_CrsGraph> &G,
const LinearOp & Op);
868 double norm_1(
const MultiVector & v,std::size_t col);
872 double norm_2(
const MultiVector & v,std::size_t col);
877 void clipLower(MultiVector & v,
double lowerBound);
882 void clipUpper(MultiVector & v,
double upperBound);
887 void replaceValue(MultiVector & v,
double currentValue,
double newValue);
891 void columnAverages(
const MultiVector & v,std::vector<double> & averages);
895 double average(
const MultiVector & v);
899 bool isPhysicallyBlockedLinearOp(
const LinearOp & op);
903 Teuchos::RCP<const Thyra::PhysicallyBlockedLinearOpBase<double> > getPhysicallyBlockedLinearOp(
const LinearOp & op, ST *scalar,
bool *transp);
908 #ifdef TEKO_DEFINED_MSC_EXTENSIONS
909 #undef _MSC_EXTENSIONS