Teko  Version of the Day
 All Classes Files Functions Variables Pages
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 
94 namespace Teko {
95 
96 using Thyra::multiply;
97 using Thyra::scale;
98 using Thyra::add;
99 using Thyra::identity;
100 using Thyra::zero; // make it to take one argument (square matrix)
101 using Thyra::block2x2;
102 using Thyra::block2x1;
103 using Thyra::block1x2;
104 
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);
125 
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);
150 
157 const 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
199 typedef Teuchos::RCP<const Thyra::VectorSpaceBase<double> > VectorSpace;
200 
201 // ----------------------------------------------------------------------------
202 
204 
205 
206 typedef Teuchos::RCP<Thyra::ProductMultiVectorBase<double> > BlockedMultiVector;
207 typedef Teuchos::RCP<Thyra::MultiVectorBase<double> > MultiVector;
208 
210 inline MultiVector toMultiVector(BlockedMultiVector & bmv) { return bmv; }
211 
213 inline const MultiVector toMultiVector(const BlockedMultiVector & bmv) { return bmv; }
214 
216 inline const BlockedMultiVector toBlockedMultiVector(const MultiVector & bmv)
217 { return Teuchos::rcp_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(bmv); }
218 
220 inline int blockCount(const BlockedMultiVector & bmv)
221 { return bmv->productSpace()->numBlocks(); }
222 
224 inline MultiVector getBlock(int i,const BlockedMultiVector & bmv)
225 { return Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(bmv->getMultiVectorBlock(i)); }
226 
228 inline MultiVector deepcopy(const MultiVector & v)
229 { return v->clone_mv(); }
230 
232 inline MultiVector copyAndInit(const MultiVector & v,double scalar)
233 { MultiVector mv = v->clone_mv(); Thyra::assign(mv.ptr(),scalar); return mv; }
234 
236 inline BlockedMultiVector deepcopy(const BlockedMultiVector & v)
237 { return toBlockedMultiVector(v->clone_mv()); }
238 
252 inline 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 
281 inline 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 
298 BlockedMultiVector buildBlockedMultiVector(const std::vector<MultiVector> & mvs);
299 
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);
314 
316 
317 // ----------------------------------------------------------------------------
318 
320 
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;
325 
327 inline LinearOp zero(const VectorSpace & vs)
328 { return Thyra::zero<ST>(vs,vs); }
329 
331 void putScalar(const ModifiableLinearOp & op,double scalar);
332 
334 inline VectorSpace rangeSpace(const LinearOp & lo)
335 { return lo->range(); }
336 
338 inline VectorSpace domainSpace(const LinearOp & lo)
339 { return lo->domain(); }
340 
342 inline 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 
349 inline 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 
356 inline LinearOp toLinearOp(BlockedLinearOp & blo) { return blo; }
357 
359 inline const LinearOp toLinearOp(const BlockedLinearOp & blo) { return blo; }
360 
362 inline LinearOp toLinearOp(ModifiableLinearOp & blo) { return blo; }
363 
365 inline const LinearOp toLinearOp(const ModifiableLinearOp & blo) { return blo; }
366 
368 inline int blockRowCount(const BlockedLinearOp & blo)
369 { return blo->productRange()->numBlocks(); }
370 
372 inline int blockColCount(const BlockedLinearOp & blo)
373 { return blo->productDomain()->numBlocks(); }
374 
376 inline LinearOp getBlock(int i,int j,const BlockedLinearOp & blo)
377 { return blo->getBlock(i,j); }
378 
380 inline void setBlock(int i,int j,BlockedLinearOp & blo, const LinearOp & lo)
381 { return blo->setBlock(i,j,lo); }
382 
384 inline BlockedLinearOp createBlockedOp()
385 { return rcp(new Thyra::DefaultBlockedLinearOp<double>()); }
386 
398 inline void beginBlockFill(BlockedLinearOp & blo,int rowCnt,int colCnt)
399 { blo->beginBlockFill(rowCnt,colCnt); }
400 
410 inline void beginBlockFill(BlockedLinearOp & blo)
411 { blo->beginBlockFill(); }
412 
414 inline void endBlockFill(BlockedLinearOp & blo)
415 { blo->endBlockFill(); }
416 
418 BlockedLinearOp getUpperTriBlocks(const BlockedLinearOp & blo,bool callEndBlockFill=true);
419 
421 BlockedLinearOp getLowerTriBlocks(const BlockedLinearOp & blo,bool callEndBlockFill=true);
422 
442 BlockedLinearOp zeroBlockedOp(const BlockedLinearOp & blo);
443 
445 bool isZeroOp(const LinearOp op);
446 
455 ModifiableLinearOp getAbsRowSumMatrix(const LinearOp & op);
456 
465 ModifiableLinearOp getAbsRowSumInvMatrix(const LinearOp & op);
466 
474 ModifiableLinearOp getLumpedMatrix(const LinearOp & op);
475 
484 ModifiableLinearOp getInvLumpedMatrix(const LinearOp & op);
485 
487 
489 
490 
509 void applyOp(const LinearOp & A,const MultiVector & x,MultiVector & y,double alpha=1.0,double beta=0.0);
510 
511 
530 void applyTransposeOp(const LinearOp & A,const MultiVector & x,MultiVector & y,double alpha=1.0,double beta=0.0);
531 
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); }
553 
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); }
575 
585 void update(double alpha,const MultiVector & x,double beta,MultiVector & y);
586 
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); }
591 
593 inline void scale(const double alpha,MultiVector & x) { Thyra::scale<double>(alpha,x.ptr()); }
594 
596 inline void scale(const double alpha,BlockedMultiVector & x)
597 { MultiVector x_mv = toMultiVector(x); scale(alpha,x_mv); }
598 
600 inline LinearOp scale(const double alpha,ModifiableLinearOp & a)
601 { return Thyra::nonconstScale(alpha,a); }
602 
604 inline LinearOp adjoint(ModifiableLinearOp & a)
605 { return Thyra::nonconstAdjoint(a); }
606 
608 
610 
611 
623 const ModifiableLinearOp getDiagonalOp(const LinearOp & op);
624 
630 const MultiVector getDiagonal(const LinearOp & op);
631 
643 const ModifiableLinearOp getInvDiagonalOp(const LinearOp & op);
644 
657 const LinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opm,const LinearOp & opr);
658 
673 const ModifiableLinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opm,const LinearOp & opr,
674  const ModifiableLinearOp & destOp);
675 
686 const LinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opr);
687 
701 const ModifiableLinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opr,
702  const ModifiableLinearOp & destOp);
703 
714 const LinearOp explicitAdd(const LinearOp & opl,const LinearOp & opr);
715 
728 const ModifiableLinearOp explicitAdd(const LinearOp & opl,const LinearOp & opr,
729  const ModifiableLinearOp & destOp);
730 
733 const ModifiableLinearOp explicitSum(const LinearOp & opl,
734  const ModifiableLinearOp & destOp);
735 
739 const LinearOp explicitTranspose(const LinearOp & op);
740 
743 double frobeniusNorm(const LinearOp & op);
744 double oneNorm(const LinearOp & op);
745 double infNorm(const LinearOp & op);
746 
750 const LinearOp buildDiagonal(const MultiVector & v,const std::string & lbl="ANYM");
751 
755 const LinearOp buildInvDiagonal(const MultiVector & v,const std::string & lbl="ANYM");
756 
758 
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);
784 
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);
810 
812 typedef enum { Diagonal
813  , Lumped
814  , AbsRowSum
815  , BlkDiag
816  , NotDiag
817  } DiagonalType;
818 
827 ModifiableLinearOp getDiagonalOp(const Teko::LinearOp & A,const DiagonalType & dt);
828 
837 ModifiableLinearOp getInvDiagonalOp(const Teko::LinearOp & A,const DiagonalType & dt);
838 
844 const MultiVector getDiagonal(const LinearOp & op,const DiagonalType & dt);
845 
852 std::string getDiagonalName(const DiagonalType & dt);
853 
862 DiagonalType getDiagonalType(std::string name);
863 
864 LinearOp probe(Teuchos::RCP<const Epetra_CrsGraph> &G, const LinearOp & Op);
865 
868 double norm_1(const MultiVector & v,std::size_t col);
869 
872 double norm_2(const MultiVector & v,std::size_t col);
873 
877 void clipLower(MultiVector & v,double lowerBound);
878 
882 void clipUpper(MultiVector & v,double upperBound);
883 
887 void replaceValue(MultiVector & v,double currentValue,double newValue);
888 
891 void columnAverages(const MultiVector & v,std::vector<double> & averages);
892 
895 double average(const MultiVector & v);
896 
899 bool isPhysicallyBlockedLinearOp(const LinearOp & op);
900 
903 Teuchos::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