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
101using Thyra::block2x2;
102using Thyra::block2x1;
103using Thyra::block1x2;
123Teuchos::RCP<Epetra_CrsMatrix> buildGraphLaplacian(
int dim,
double * coords,
const Epetra_CrsMatrix & stencil);
124Teuchos::RCP<Tpetra::CrsMatrix<ST,LO,GO,NT> > buildGraphLaplacian(
int dim,ST * coords,
const Tpetra::CrsMatrix<ST,LO,GO,NT> & stencil);
148Teuchos::RCP<Epetra_CrsMatrix> buildGraphLaplacian(
double * x,
double * y,
double * z,
int stride,
const Epetra_CrsMatrix & stencil);
149Teuchos::RCP<Tpetra::CrsMatrix<ST,LO,GO,NT> > buildGraphLaplacian(ST * x,ST * y,ST * z,GO stride,
const Tpetra::CrsMatrix<ST,LO,GO,NT> & stencil);
157const 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)
199typedef Teuchos::RCP<const Thyra::VectorSpaceBase<double> > VectorSpace;
206typedef Teuchos::RCP<Thyra::ProductMultiVectorBase<double> > BlockedMultiVector;
207typedef Teuchos::RCP<Thyra::MultiVectorBase<double> > MultiVector;
213inline const MultiVector
toMultiVector(
const BlockedMultiVector & bmv) {
return bmv; }
217{
return Teuchos::rcp_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(bmv); }
221{
return bmv->productSpace()->numBlocks(); }
224inline MultiVector
getBlock(
int i,
const BlockedMultiVector & bmv)
225{
return Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(bmv->getMultiVectorBlock(i)); }
229{
return v->clone_mv(); }
232inline MultiVector
copyAndInit(
const MultiVector & v,
double scalar)
233{ MultiVector mv = v->clone_mv(); Thyra::assign(mv.ptr(),scalar);
return mv; }
236inline BlockedMultiVector
deepcopy(
const BlockedMultiVector & v)
252inline MultiVector
datacopy(
const MultiVector & src,MultiVector & dst)
254 if(dst==Teuchos::null)
257 bool rangeCompat = src->range()->isCompatible(*dst->range());
258 bool domainCompat = src->domain()->isCompatible(*dst->domain());
260 if(not (rangeCompat && domainCompat))
264 Thyra::assign<double>(dst.ptr(),*src);
281inline BlockedMultiVector
datacopy(
const BlockedMultiVector & src,BlockedMultiVector & dst)
283 if(dst==Teuchos::null)
286 bool rangeCompat = src->range()->isCompatible(*dst->range());
287 bool domainCompat = src->domain()->isCompatible(*dst->domain());
289 if(not (rangeCompat && domainCompat))
293 Thyra::assign<double>(dst.ptr(),*src);
298BlockedMultiVector buildBlockedMultiVector(
const std::vector<MultiVector> & mvs);
310Teuchos::RCP<Thyra::VectorBase<double> > indicatorVector(
311 const std::vector<int> & indices,
312 const VectorSpace & vs,
313 double onValue=1.0,
double offValue=0.0);
321typedef Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<ST> > BlockedLinearOp;
322typedef Teuchos::RCP<const Thyra::LinearOpBase<ST> > LinearOp;
323typedef Teuchos::RCP<Thyra::LinearOpBase<ST> > InverseLinearOp;
324typedef Teuchos::RCP<Thyra::LinearOpBase<ST> > ModifiableLinearOp;
327inline LinearOp
zero(
const VectorSpace & vs)
328{
return Thyra::zero<ST>(vs,vs); }
331void putScalar(
const ModifiableLinearOp & op,
double scalar);
335{
return lo->range(); }
339{
return lo->domain(); }
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);
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);
356inline LinearOp
toLinearOp(BlockedLinearOp & blo) {
return blo; }
359inline const LinearOp
toLinearOp(
const BlockedLinearOp & blo) {
return blo; }
362inline LinearOp
toLinearOp(ModifiableLinearOp & blo) {
return blo; }
365inline const LinearOp
toLinearOp(
const ModifiableLinearOp & blo) {
return blo; }
369{
return blo->productRange()->numBlocks(); }
373{
return blo->productDomain()->numBlocks(); }
376inline LinearOp
getBlock(
int i,
int j,
const BlockedLinearOp & blo)
377{
return blo->getBlock(i,j); }
380inline void setBlock(
int i,
int j,BlockedLinearOp & blo,
const LinearOp & lo)
381{
return blo->setBlock(i,j,lo); }
385{
return rcp(
new Thyra::DefaultBlockedLinearOp<double>()); }
399{ blo->beginBlockFill(rowCnt,colCnt); }
411{ blo->beginBlockFill(); }
415{ blo->endBlockFill(); }
418BlockedLinearOp getUpperTriBlocks(
const BlockedLinearOp & blo,
bool callEndBlockFill=
true);
421BlockedLinearOp getLowerTriBlocks(
const BlockedLinearOp & blo,
bool callEndBlockFill=
true);
442BlockedLinearOp zeroBlockedOp(
const BlockedLinearOp & blo);
445bool isZeroOp(
const LinearOp op);
455ModifiableLinearOp getAbsRowSumMatrix(
const LinearOp & op);
465ModifiableLinearOp getAbsRowSumInvMatrix(
const LinearOp & op);
474ModifiableLinearOp getLumpedMatrix(
const LinearOp & op);
484ModifiableLinearOp getInvLumpedMatrix(
const LinearOp & op);
509void applyOp(
const LinearOp & A,
const MultiVector & x,MultiVector & y,
double alpha=1.0,
double beta=0.0);
530void applyTransposeOp(
const LinearOp & A,
const MultiVector & x,MultiVector & y,
double alpha=1.0,
double beta=0.0);
550inline void applyOp(
const LinearOp & A,
const BlockedMultiVector & x,BlockedMultiVector & y,
double alpha=1.0,
double beta=0.0)
552 applyOp(A,x_mv,y_mv,alpha,beta); }
572inline void applyTransposeOp(
const LinearOp & A,
const BlockedMultiVector & x,BlockedMultiVector & y,
double alpha=1.0,
double beta=0.0)
574 applyTransposeOp(A,x_mv,y_mv,alpha,beta); }
585void update(
double alpha,
const MultiVector & x,
double beta,MultiVector & y);
588inline void update(
double alpha,
const BlockedMultiVector & x,
double beta,BlockedMultiVector & y)
590 update(alpha,x_mv,beta,y_mv); }
593inline void scale(
const double alpha,MultiVector & x) { Thyra::scale<double>(alpha,x.ptr()); }
596inline void scale(
const double alpha,BlockedMultiVector & x)
600inline LinearOp
scale(
const double alpha,ModifiableLinearOp & a)
601{
return Thyra::nonconstScale(alpha,a); }
604inline LinearOp
adjoint(ModifiableLinearOp & a)
605{
return Thyra::nonconstAdjoint(a); }
623const ModifiableLinearOp getDiagonalOp(
const LinearOp & op);
630const MultiVector getDiagonal(
const LinearOp & op);
643const ModifiableLinearOp getInvDiagonalOp(
const LinearOp & op);
657const LinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opm,
const LinearOp & opr);
673const ModifiableLinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opm,
const LinearOp & opr,
674 const ModifiableLinearOp & destOp);
686const LinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opr);
701const ModifiableLinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opr,
702 const ModifiableLinearOp & destOp);
714const LinearOp explicitAdd(
const LinearOp & opl,
const LinearOp & opr);
728const ModifiableLinearOp explicitAdd(
const LinearOp & opl,
const LinearOp & opr,
729 const ModifiableLinearOp & destOp);
733const ModifiableLinearOp explicitSum(
const LinearOp & opl,
734 const ModifiableLinearOp & destOp);
739const LinearOp explicitTranspose(
const LinearOp & op);
743double frobeniusNorm(
const LinearOp & op);
744double oneNorm(
const LinearOp & op);
745double infNorm(
const LinearOp & op);
750const LinearOp buildDiagonal(
const MultiVector & v,
const std::string & lbl=
"ANYM");
755const LinearOp buildInvDiagonal(
const MultiVector & v,
const std::string & lbl=
"ANYM");
782double computeSpectralRad(
const Teuchos::RCP<
const Thyra::LinearOpBase<double> > & A,
double tol,
783 bool isHermitian=
false,
int numBlocks=5,
int restart=0,
int verbosity=0);
808double computeSmallestMagEig(
const Teuchos::RCP<
const Thyra::LinearOpBase<double> > & A,
double tol,
809 bool isHermitian=
false,
int numBlocks=5,
int restart=0,
int verbosity=0);
827ModifiableLinearOp getDiagonalOp(
const Teko::LinearOp & A,
const DiagonalType & dt);
837ModifiableLinearOp getInvDiagonalOp(
const Teko::LinearOp & A,
const DiagonalType & dt);
844const MultiVector getDiagonal(
const LinearOp & op,
const DiagonalType & dt);
852std::string getDiagonalName(
const DiagonalType & dt);
862DiagonalType getDiagonalType(std::string name);
864LinearOp probe(Teuchos::RCP<const Epetra_CrsGraph> &G,
const LinearOp & Op);
868double norm_1(
const MultiVector & v,std::size_t col);
872double norm_2(
const MultiVector & v,std::size_t col);
877void clipLower(MultiVector & v,
double lowerBound);
882void clipUpper(MultiVector & v,
double upperBound);
887void replaceValue(MultiVector & v,
double currentValue,
double newValue);
891void columnAverages(
const MultiVector & v,std::vector<double> & averages);
895double average(
const MultiVector & v);
899bool isPhysicallyBlockedLinearOp(
const LinearOp & op);
903Teuchos::RCP<const Thyra::PhysicallyBlockedLinearOpBase<double> > getPhysicallyBlockedLinearOp(
const LinearOp & op, ST *scalar,
bool *transp);
908#ifdef TEKO_DEFINED_MSC_EXTENSIONS
909#undef _MSC_EXTENSIONS
void scale(const double alpha, MultiVector &x)
Scale a multivector by a constant.
MultiVector datacopy(const MultiVector &src, MultiVector &dst)
Copy the contents of a multivector to a destination vector.
void beginBlockFill(BlockedLinearOp &blo, int rowCnt, int colCnt)
Let the blocked operator know that you are going to set the sub blocks.
@ BlkDiag
Specifies that a block diagonal approximation is to be used.
@ NotDiag
For user convenience, if Teko recieves this value, exceptions will be thrown
@ AbsRowSum
Specifies that the diagonal entry is .
@ Diagonal
Specifies that just the diagonal is used.
@ Lumped
Specifies that row sum is used to form a diagonal.
const BlockedMultiVector toBlockedMultiVector(const MultiVector &bmv)
Convert to a BlockedMultiVector from a MultiVector.
LinearOp toLinearOp(BlockedLinearOp &blo)
Convert to a LinearOp from a BlockedLinearOp.
int blockRowCount(const BlockedLinearOp &blo)
Get the row count in a block linear operator.
MultiVector toMultiVector(BlockedMultiVector &bmv)
Convert to a MultiVector from a BlockedMultiVector.
int blockCount(const BlockedMultiVector &bmv)
Get the column count in a block linear operator.
MultiVector getBlock(int i, const BlockedMultiVector &bmv)
Get the ith block from a BlockedMultiVector object.
void setBlock(int i, int j, BlockedLinearOp &blo, const LinearOp &lo)
Set the i,j block in a BlockedLinearOp object.
VectorSpace rangeSpace(const LinearOp &lo)
Get the range space of a linear operator.
MultiVector copyAndInit(const MultiVector &v, double scalar)
Perform a deep copy of the vector.
LinearOp zero(const VectorSpace &vs)
Build a square zero operator from a single vector space.
MultiVector deepcopy(const MultiVector &v)
Perform a deep copy of the vector.
int blockColCount(const BlockedLinearOp &blo)
Get the column count in a block linear operator.
BlockedLinearOp createBlockedOp()
Build a new blocked linear operator.
LinearOp adjoint(ModifiableLinearOp &a)
Construct an implicit adjoint of the linear operators.
BlockedLinearOp toBlockedLinearOp(LinearOp &clo)
Converts a LinearOp to a BlockedLinearOp.
void endBlockFill(BlockedLinearOp &blo)
Notify the blocked operator that the fill stage is completed.
VectorSpace domainSpace(const LinearOp &lo)
Get the domain space of a linear operator.