Teko Version of the Day
Teko_Utilities.hpp
Go to the documentation of this file.
1/*
2// @HEADER
3//
4// ***********************************************************************
5//
6// Teko: A package for block and physics based preconditioning
7// Copyright 2010 Sandia Corporation
8//
9// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
10// the U.S. Government retains certain rights in this software.
11//
12// Redistribution and use in source and binary forms, with or without
13// modification, are permitted provided that the following conditions are
14// met:
15//
16// 1. Redistributions of source code must retain the above copyright
17// notice, this list of conditions and the following disclaimer.
18//
19// 2. Redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution.
22//
23// 3. Neither the name of the Corporation nor the names of the
24// contributors may be used to endorse or promote products derived from
25// this software without specific prior written permission.
26//
27// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
28// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
31// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38//
39// Questions? Contact Eric C. Cyr (eccyr@sandia.gov)
40//
41// ***********************************************************************
42//
43// @HEADER
44
45*/
46
55#ifndef __Teko_Utilities_hpp__
56#define __Teko_Utilities_hpp__
57
58#include "Epetra_CrsMatrix.h"
59#include "Tpetra_CrsMatrix.hpp"
60
61// Teuchos includes
62#include "Teuchos_VerboseObject.hpp"
63
64// Thyra includes
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"
80
81#include "Teko_ConfigDefs.hpp"
82
83#ifdef _MSC_VER
84#ifndef _MSC_EXTENSIONS
85#define _MSC_EXTENSIONS
86#define TEKO_DEFINED_MSC_EXTENSIONS
87#endif
88#include <iso646.h> // For C alternative tokens
89#endif
90
91// #define Teko_DEBUG_OFF
92#define Teko_DEBUG_INT 5
93
94namespace Teko {
95
96using Thyra::multiply;
97using Thyra::scale;
98using Thyra::add;
99using Thyra::identity;
100using Thyra::zero; // make it to take one argument (square matrix)
101using Thyra::block2x2;
102using Thyra::block2x1;
103using Thyra::block1x2;
104
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);
125
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);
150
157const Teuchos::RCP<Teuchos::FancyOStream> getOutputStream();
158// inline const Teuchos::RCP<Teuchos::FancyOStream> getOutputStream();
159// { return Teuchos::VerboseObjectBase::getDefaultOStream(); }
160
161#ifndef Teko_DEBUG_OFF
162//#if 0
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)
178
179// struct __DebugScope__ {
180// __DebugScope__(const std::string & str,int level)
181// : str_(str), level_(level)
182// { Teko_DEBUG_MSG("BEGIN "+str_,level_); Teko_DEBUG_PUSHTAB(); }
183// ~__DebugScope__()
184// { Teko_DEBUG_POPTAB(); Teko_DEBUG_MSG("END "+str_,level_); }
185// std::string str_; int level_; };
186// #define Teko_DEBUG_SCOPE(str,level) __DebugScope__ __dbgScope__(str,level);
187#else
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)
196#endif
197
198// typedefs for increased simplicity
199typedef Teuchos::RCP<const Thyra::VectorSpaceBase<double> > VectorSpace;
200
201// ----------------------------------------------------------------------------
202
204
205
206typedef Teuchos::RCP<Thyra::ProductMultiVectorBase<double> > BlockedMultiVector;
207typedef Teuchos::RCP<Thyra::MultiVectorBase<double> > MultiVector;
208
210inline MultiVector toMultiVector(BlockedMultiVector & bmv) { return bmv; }
211
213inline const MultiVector toMultiVector(const BlockedMultiVector & bmv) { return bmv; }
214
216inline const BlockedMultiVector toBlockedMultiVector(const MultiVector & bmv)
217{ return Teuchos::rcp_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(bmv); }
218
220inline int blockCount(const BlockedMultiVector & bmv)
221{ return bmv->productSpace()->numBlocks(); }
222
224inline MultiVector getBlock(int i,const BlockedMultiVector & bmv)
225{ return Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(bmv->getMultiVectorBlock(i)); }
226
228inline MultiVector deepcopy(const MultiVector & v)
229{ return v->clone_mv(); }
230
232inline MultiVector copyAndInit(const MultiVector & v,double scalar)
233{ MultiVector mv = v->clone_mv(); Thyra::assign(mv.ptr(),scalar); return mv; }
234
236inline BlockedMultiVector deepcopy(const BlockedMultiVector & v)
237{ return toBlockedMultiVector(v->clone_mv()); }
238
252inline MultiVector datacopy(const MultiVector & src,MultiVector & dst)
253{
254 if(dst==Teuchos::null)
255 return deepcopy(src);
256
257 bool rangeCompat = src->range()->isCompatible(*dst->range());
258 bool domainCompat = src->domain()->isCompatible(*dst->domain());
259
260 if(not (rangeCompat && domainCompat))
261 return deepcopy(src);
262
263 // perform data copy
264 Thyra::assign<double>(dst.ptr(),*src);
265 return dst;
266}
267
281inline BlockedMultiVector datacopy(const BlockedMultiVector & src,BlockedMultiVector & dst)
282{
283 if(dst==Teuchos::null)
284 return deepcopy(src);
285
286 bool rangeCompat = src->range()->isCompatible(*dst->range());
287 bool domainCompat = src->domain()->isCompatible(*dst->domain());
288
289 if(not (rangeCompat && domainCompat))
290 return deepcopy(src);
291
292 // perform data copy
293 Thyra::assign<double>(dst.ptr(),*src);
294 return dst;
295}
296
298BlockedMultiVector buildBlockedMultiVector(const std::vector<MultiVector> & mvs);
299
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);
314
316
317// ----------------------------------------------------------------------------
318
320
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;
325
327inline LinearOp zero(const VectorSpace & vs)
328{ return Thyra::zero<ST>(vs,vs); }
329
331void putScalar(const ModifiableLinearOp & op,double scalar);
332
334inline VectorSpace rangeSpace(const LinearOp & lo)
335{ return lo->range(); }
336
338inline VectorSpace domainSpace(const LinearOp & lo)
339{ return lo->domain(); }
340
342inline BlockedLinearOp toBlockedLinearOp(LinearOp & clo)
343{
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);
346}
347
349inline const BlockedLinearOp toBlockedLinearOp(const LinearOp & clo)
350{
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);
353}
354
356inline LinearOp toLinearOp(BlockedLinearOp & blo) { return blo; }
357
359inline const LinearOp toLinearOp(const BlockedLinearOp & blo) { return blo; }
360
362inline LinearOp toLinearOp(ModifiableLinearOp & blo) { return blo; }
363
365inline const LinearOp toLinearOp(const ModifiableLinearOp & blo) { return blo; }
366
368inline int blockRowCount(const BlockedLinearOp & blo)
369{ return blo->productRange()->numBlocks(); }
370
372inline int blockColCount(const BlockedLinearOp & blo)
373{ return blo->productDomain()->numBlocks(); }
374
376inline LinearOp getBlock(int i,int j,const BlockedLinearOp & blo)
377{ return blo->getBlock(i,j); }
378
380inline void setBlock(int i,int j,BlockedLinearOp & blo, const LinearOp & lo)
381{ return blo->setBlock(i,j,lo); }
382
384inline BlockedLinearOp createBlockedOp()
385{ return rcp(new Thyra::DefaultBlockedLinearOp<double>()); }
386
398inline void beginBlockFill(BlockedLinearOp & blo,int rowCnt,int colCnt)
399{ blo->beginBlockFill(rowCnt,colCnt); }
400
410inline void beginBlockFill(BlockedLinearOp & blo)
411{ blo->beginBlockFill(); }
412
414inline void endBlockFill(BlockedLinearOp & blo)
415{ blo->endBlockFill(); }
416
418BlockedLinearOp getUpperTriBlocks(const BlockedLinearOp & blo,bool callEndBlockFill=true);
419
421BlockedLinearOp getLowerTriBlocks(const BlockedLinearOp & blo,bool callEndBlockFill=true);
422
442BlockedLinearOp zeroBlockedOp(const BlockedLinearOp & blo);
443
445bool isZeroOp(const LinearOp op);
446
455ModifiableLinearOp getAbsRowSumMatrix(const LinearOp & op);
456
465ModifiableLinearOp getAbsRowSumInvMatrix(const LinearOp & op);
466
474ModifiableLinearOp getLumpedMatrix(const LinearOp & op);
475
484ModifiableLinearOp getInvLumpedMatrix(const LinearOp & op);
485
487
489
490
509void applyOp(const LinearOp & A,const MultiVector & x,MultiVector & y,double alpha=1.0,double beta=0.0);
510
511
530void applyTransposeOp(const LinearOp & A,const MultiVector & x,MultiVector & y,double alpha=1.0,double beta=0.0);
531
550inline 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); }
553
572inline 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); }
575
585void update(double alpha,const MultiVector & x,double beta,MultiVector & y);
586
588inline 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); }
591
593inline void scale(const double alpha,MultiVector & x) { Thyra::scale<double>(alpha,x.ptr()); }
594
596inline void scale(const double alpha,BlockedMultiVector & x)
597{ MultiVector x_mv = toMultiVector(x); scale(alpha,x_mv); }
598
600inline LinearOp scale(const double alpha,ModifiableLinearOp & a)
601{ return Thyra::nonconstScale(alpha,a); }
602
604inline LinearOp adjoint(ModifiableLinearOp & a)
605{ return Thyra::nonconstAdjoint(a); }
606
608
610
611
623const ModifiableLinearOp getDiagonalOp(const LinearOp & op);
624
630const MultiVector getDiagonal(const LinearOp & op);
631
643const ModifiableLinearOp getInvDiagonalOp(const LinearOp & op);
644
657const LinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opm,const LinearOp & opr);
658
673const ModifiableLinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opm,const LinearOp & opr,
674 const ModifiableLinearOp & destOp);
675
686const LinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opr);
687
701const ModifiableLinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opr,
702 const ModifiableLinearOp & destOp);
703
714const LinearOp explicitAdd(const LinearOp & opl,const LinearOp & opr);
715
728const ModifiableLinearOp explicitAdd(const LinearOp & opl,const LinearOp & opr,
729 const ModifiableLinearOp & destOp);
730
733const ModifiableLinearOp explicitSum(const LinearOp & opl,
734 const ModifiableLinearOp & destOp);
735
739const LinearOp explicitTranspose(const LinearOp & op);
740
743double frobeniusNorm(const LinearOp & op);
744double oneNorm(const LinearOp & op);
745double infNorm(const LinearOp & op);
746
750const LinearOp buildDiagonal(const MultiVector & v,const std::string & lbl="ANYM");
751
755const LinearOp buildInvDiagonal(const MultiVector & v,const std::string & lbl="ANYM");
756
758
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);
784
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);
810
812typedef enum { Diagonal
817 } DiagonalType;
818
827ModifiableLinearOp getDiagonalOp(const Teko::LinearOp & A,const DiagonalType & dt);
828
837ModifiableLinearOp getInvDiagonalOp(const Teko::LinearOp & A,const DiagonalType & dt);
838
844const MultiVector getDiagonal(const LinearOp & op,const DiagonalType & dt);
845
852std::string getDiagonalName(const DiagonalType & dt);
853
862DiagonalType getDiagonalType(std::string name);
863
864LinearOp probe(Teuchos::RCP<const Epetra_CrsGraph> &G, const LinearOp & Op);
865
868double norm_1(const MultiVector & v,std::size_t col);
869
872double norm_2(const MultiVector & v,std::size_t col);
873
877void clipLower(MultiVector & v,double lowerBound);
878
882void clipUpper(MultiVector & v,double upperBound);
883
887void replaceValue(MultiVector & v,double currentValue,double newValue);
888
891void columnAverages(const MultiVector & v,std::vector<double> & averages);
892
895double average(const MultiVector & v);
896
899bool isPhysicallyBlockedLinearOp(const LinearOp & op);
900
903Teuchos::RCP<const Thyra::PhysicallyBlockedLinearOpBase<double> > getPhysicallyBlockedLinearOp(const LinearOp & op, ST *scalar, bool *transp);
904
905} // end namespace Teko
906
907#ifdef _MSC_VER
908#ifdef TEKO_DEFINED_MSC_EXTENSIONS
909#undef _MSC_EXTENSIONS
910#endif
911#endif
912
913#endif
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.