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 
60 // Teuchos includes
61 #include "Teuchos_VerboseObject.hpp"
62 
63 // Thyra includes
64 #include "Thyra_LinearOpBase.hpp"
65 #include "Thyra_PhysicallyBlockedLinearOpBase.hpp"
66 #include "Thyra_ProductVectorSpaceBase.hpp"
67 #include "Thyra_VectorSpaceBase.hpp"
68 #include "Thyra_ProductMultiVectorBase.hpp"
69 #include "Thyra_MultiVectorStdOps.hpp"
70 #include "Thyra_MultiVectorBase.hpp"
71 #include "Thyra_VectorBase.hpp"
72 #include "Thyra_VectorStdOps.hpp"
73 #include "Thyra_DefaultBlockedLinearOp.hpp"
74 #include "Thyra_DefaultMultipliedLinearOp.hpp"
75 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
76 #include "Thyra_DefaultAddedLinearOp.hpp"
77 #include "Thyra_DefaultIdentityLinearOp.hpp"
78 #include "Thyra_DefaultZeroLinearOp.hpp"
79 
80 #ifdef _MSC_VER
81 #ifndef _MSC_EXTENSIONS
82 #define _MSC_EXTENSIONS
83 #define TEKO_DEFINED_MSC_EXTENSIONS
84 #endif
85 #include <iso646.h> // For C alternative tokens
86 #endif
87 
88 // #define Teko_DEBUG_OFF
89 #define Teko_DEBUG_INT 5
90 
91 namespace Teko {
92 
93 using Thyra::multiply;
94 using Thyra::scale;
95 using Thyra::add;
96 using Thyra::identity;
97 using Thyra::zero; // make it to take one argument (square matrix)
98 using Thyra::block2x2;
99 using Thyra::block2x1;
100 using Thyra::block1x2;
101 
120 Teuchos::RCP<Epetra_CrsMatrix> buildGraphLaplacian(int dim,double * coords,const Epetra_CrsMatrix & stencil);
121 
144 Teuchos::RCP<Epetra_CrsMatrix> buildGraphLaplacian(double * x,double * y,double * z,int stride,const Epetra_CrsMatrix & stencil);
145 
152 const Teuchos::RCP<Teuchos::FancyOStream> getOutputStream();
153 // inline const Teuchos::RCP<Teuchos::FancyOStream> getOutputStream();
154 // { return Teuchos::VerboseObjectBase::getDefaultOStream(); }
155 
156 #ifndef Teko_DEBUG_OFF
157  #define Teko_DEBUG_EXPR(str) str
158  #define Teko_DEBUG_MSG(str,level) if(level<=Teko_DEBUG_INT) { \
159  Teuchos::RCP<Teuchos::FancyOStream> out = Teko::getOutputStream(); \
160  *out << "Teko: " << str << std::endl; }
161  #define Teko_DEBUG_MSG_BEGIN(level) if(level<=Teko_DEBUG_INT) { \
162  Teko::getOutputStream()->pushTab(3); \
163  *Teko::getOutputStream() << "Teko: Begin debug MSG\n"; \
164  std::ostream & DEBUG_STREAM = *Teko::getOutputStream(); \
165  Teko::getOutputStream()->pushTab(3);
166  #define Teko_DEBUG_MSG_END() Teko::getOutputStream()->popTab(); \
167  *Teko::getOutputStream() << "Teko: End debug MSG\n"; \
168  Teko::getOutputStream()->popTab(); }
169  #define Teko_DEBUG_PUSHTAB() Teko::getOutputStream()->pushTab(3)
170  #define Teko_DEBUG_POPTAB() Teko::getOutputStream()->popTab()
171 
172  struct __DebugScope__ {
173  __DebugScope__(const std::string & str,int level)
174  : str_(str), level_(level)
175  { Teko_DEBUG_MSG("BEGIN "+str_,level_); Teko_DEBUG_PUSHTAB(); }
176  ~__DebugScope__()
177  { Teko_DEBUG_POPTAB(); Teko_DEBUG_MSG("END "+str_,level_); }
178  std::string str_; int level_; };
179  #define Teko_DEBUG_SCOPE(str,level) __DebugScope__ __dbgScope__(str,level);
180 #else
181  #define Teko_DEBUG_EXPR(str)
182  #define Teko_DEBUG_MSG(str,level)
183  #define Teko_DEBUG_MSG_BEGIN(level) if(false) { \
184  std::ostream & DEBUG_STREAM = *Teko::getOutputStream();
185  #define Teko_DEBUG_MSG_END() }
186  #define Teko_DEBUG_PUSHTAB()
187  #define Teko_DEBUG_POPTAB()
188  #define Teko_DEBUG_SCOPE(str,level)
189 #endif
190 
191 // typedefs for increased simplicity
192 typedef Teuchos::RCP<const Thyra::VectorSpaceBase<double> > VectorSpace;
193 
194 // ----------------------------------------------------------------------------
195 
197 
198 
199 typedef Teuchos::RCP<Thyra::ProductMultiVectorBase<double> > BlockedMultiVector;
200 typedef Teuchos::RCP<Thyra::MultiVectorBase<double> > MultiVector;
201 
203 inline MultiVector toMultiVector(BlockedMultiVector & bmv) { return bmv; }
204 
206 inline const MultiVector toMultiVector(const BlockedMultiVector & bmv) { return bmv; }
207 
209 inline const BlockedMultiVector toBlockedMultiVector(const MultiVector & bmv)
210 { return Teuchos::rcp_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(bmv); }
211 
213 inline int blockCount(const BlockedMultiVector & bmv)
214 { return bmv->productSpace()->numBlocks(); }
215 
217 inline MultiVector getBlock(int i,const BlockedMultiVector & bmv)
218 { return Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(bmv->getMultiVectorBlock(i)); }
219 
221 inline MultiVector deepcopy(const MultiVector & v)
222 { return v->clone_mv(); }
223 
225 inline MultiVector copyAndInit(const MultiVector & v,double scalar)
226 { MultiVector mv = v->clone_mv(); Thyra::assign(mv.ptr(),scalar); return mv; }
227 
229 inline BlockedMultiVector deepcopy(const BlockedMultiVector & v)
230 { return toBlockedMultiVector(v->clone_mv()); }
231 
245 inline MultiVector datacopy(const MultiVector & src,MultiVector & dst)
246 {
247  if(dst==Teuchos::null)
248  return deepcopy(src);
249 
250  bool rangeCompat = src->range()->isCompatible(*dst->range());
251  bool domainCompat = src->domain()->isCompatible(*dst->domain());
252 
253  if(not (rangeCompat && domainCompat))
254  return deepcopy(src);
255 
256  // perform data copy
257  Thyra::assign<double>(dst.ptr(),*src);
258  return dst;
259 }
260 
274 inline BlockedMultiVector datacopy(const BlockedMultiVector & src,BlockedMultiVector & dst)
275 {
276  if(dst==Teuchos::null)
277  return deepcopy(src);
278 
279  bool rangeCompat = src->range()->isCompatible(*dst->range());
280  bool domainCompat = src->domain()->isCompatible(*dst->domain());
281 
282  if(not (rangeCompat && domainCompat))
283  return deepcopy(src);
284 
285  // perform data copy
286  Thyra::assign<double>(dst.ptr(),*src);
287  return dst;
288 }
289 
291 BlockedMultiVector buildBlockedMultiVector(const std::vector<MultiVector> & mvs);
292 
303 Teuchos::RCP<Thyra::VectorBase<double> > indicatorVector(
304  const std::vector<int> & indices,
305  const VectorSpace & vs,
306  double onValue=1.0, double offValue=0.0);
307 
309 
310 // ----------------------------------------------------------------------------
311 
313 
314 typedef Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<double> > BlockedLinearOp;
315 typedef Teuchos::RCP<const Thyra::LinearOpBase<double> > LinearOp;
316 typedef Teuchos::RCP<Thyra::LinearOpBase<double> > InverseLinearOp;
317 typedef Teuchos::RCP<Thyra::LinearOpBase<double> > ModifiableLinearOp;
318 
320 inline LinearOp zero(const VectorSpace & vs)
321 { return Thyra::zero<double>(vs,vs); }
322 
324 void putScalar(const ModifiableLinearOp & op,double scalar);
325 
327 inline VectorSpace rangeSpace(const LinearOp & lo)
328 { return lo->range(); }
329 
331 inline VectorSpace domainSpace(const LinearOp & lo)
332 { return lo->domain(); }
333 
335 inline BlockedLinearOp toBlockedLinearOp(LinearOp & clo)
336 {
337  Teuchos::RCP<Thyra::LinearOpBase<double> > lo = Teuchos::rcp_const_cast<Thyra::LinearOpBase<double> >(clo);
338  return Teuchos::rcp_dynamic_cast<Thyra::PhysicallyBlockedLinearOpBase<double> > (lo);
339 }
340 
342 inline const BlockedLinearOp toBlockedLinearOp(const 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 LinearOp toLinearOp(BlockedLinearOp & blo) { return blo; }
350 
352 inline const LinearOp toLinearOp(const BlockedLinearOp & blo) { return blo; }
353 
355 inline LinearOp toLinearOp(ModifiableLinearOp & blo) { return blo; }
356 
358 inline const LinearOp toLinearOp(const ModifiableLinearOp & blo) { return blo; }
359 
361 inline int blockRowCount(const BlockedLinearOp & blo)
362 { return blo->productRange()->numBlocks(); }
363 
365 inline int blockColCount(const BlockedLinearOp & blo)
366 { return blo->productDomain()->numBlocks(); }
367 
369 inline LinearOp getBlock(int i,int j,const BlockedLinearOp & blo)
370 { return blo->getBlock(i,j); }
371 
373 inline void setBlock(int i,int j,BlockedLinearOp & blo, const LinearOp & lo)
374 { return blo->setBlock(i,j,lo); }
375 
377 inline BlockedLinearOp createBlockedOp()
378 { return rcp(new Thyra::DefaultBlockedLinearOp<double>()); }
379 
391 inline void beginBlockFill(BlockedLinearOp & blo,int rowCnt,int colCnt)
392 { blo->beginBlockFill(rowCnt,colCnt); }
393 
403 inline void beginBlockFill(BlockedLinearOp & blo)
404 { blo->beginBlockFill(); }
405 
407 inline void endBlockFill(BlockedLinearOp & blo)
408 { blo->endBlockFill(); }
409 
411 BlockedLinearOp getUpperTriBlocks(const BlockedLinearOp & blo,bool callEndBlockFill=true);
412 
414 BlockedLinearOp getLowerTriBlocks(const BlockedLinearOp & blo,bool callEndBlockFill=true);
415 
435 BlockedLinearOp zeroBlockedOp(const BlockedLinearOp & blo);
436 
438 bool isZeroOp(const LinearOp op);
439 
448 ModifiableLinearOp getAbsRowSumMatrix(const LinearOp & op);
449 
458 ModifiableLinearOp getAbsRowSumInvMatrix(const LinearOp & op);
459 
467 ModifiableLinearOp getLumpedMatrix(const LinearOp & op);
468 
477 ModifiableLinearOp getInvLumpedMatrix(const LinearOp & op);
478 
480 
482 
483 
502 void applyOp(const LinearOp & A,const MultiVector & x,MultiVector & y,double alpha=1.0,double beta=0.0);
503 
522 inline void applyOp(const LinearOp & A,const BlockedMultiVector & x,BlockedMultiVector & y,double alpha=1.0,double beta=0.0)
523 { const MultiVector x_mv = toMultiVector(x); MultiVector y_mv = toMultiVector(y);
524  applyOp(A,x_mv,y_mv,alpha,beta); }
525 
535 void update(double alpha,const MultiVector & x,double beta,MultiVector & y);
536 
538 inline void update(double alpha,const BlockedMultiVector & x,double beta,BlockedMultiVector & y)
539 { MultiVector x_mv = toMultiVector(x); MultiVector y_mv = toMultiVector(y);
540  update(alpha,x_mv,beta,y_mv); }
541 
543 inline void scale(const double alpha,MultiVector & x) { Thyra::scale<double>(alpha,x.ptr()); }
544 
546 inline void scale(const double alpha,BlockedMultiVector & x)
547 { MultiVector x_mv = toMultiVector(x); scale(alpha,x_mv); }
548 
550 inline LinearOp scale(const double alpha,ModifiableLinearOp & a)
551 { return Thyra::nonconstScale(alpha,a); }
552 
554 inline LinearOp adjoint(ModifiableLinearOp & a)
555 { return Thyra::nonconstAdjoint(a); }
556 
558 
560 
561 
573 const ModifiableLinearOp getDiagonalOp(const LinearOp & op);
574 
580 const MultiVector getDiagonal(const LinearOp & op);
581 
593 const ModifiableLinearOp getInvDiagonalOp(const LinearOp & op);
594 
607 const LinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opm,const LinearOp & opr);
608 
623 const ModifiableLinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opm,const LinearOp & opr,
624  const ModifiableLinearOp & destOp);
625 
636 const LinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opr);
637 
651 const ModifiableLinearOp explicitMultiply(const LinearOp & opl,const LinearOp & opr,
652  const ModifiableLinearOp & destOp);
653 
664 const LinearOp explicitAdd(const LinearOp & opl,const LinearOp & opr);
665 
678 const ModifiableLinearOp explicitAdd(const LinearOp & opl,const LinearOp & opr,
679  const ModifiableLinearOp & destOp);
680 
683 const ModifiableLinearOp explicitSum(const LinearOp & opl,
684  const ModifiableLinearOp & destOp);
685 
689 const LinearOp explicitTranspose(const LinearOp & op);
690 
694 const LinearOp buildDiagonal(const MultiVector & v,const std::string & lbl="ANYM");
695 
699 const LinearOp buildInvDiagonal(const MultiVector & v,const std::string & lbl="ANYM");
700 
702 
726 double computeSpectralRad(const Teuchos::RCP<const Thyra::LinearOpBase<double> > & A,double tol,
727  bool isHermitian=false,int numBlocks=5,int restart=0,int verbosity=0);
728 
752 double computeSmallestMagEig(const Teuchos::RCP<const Thyra::LinearOpBase<double> > & A, double tol,
753  bool isHermitian=false,int numBlocks=5,int restart=0,int verbosity=0);
754 
756 typedef enum { Diagonal
761  } DiagonalType;
762 
771 ModifiableLinearOp getDiagonalOp(const Teko::LinearOp & A,const DiagonalType & dt);
772 
781 ModifiableLinearOp getInvDiagonalOp(const Teko::LinearOp & A,const DiagonalType & dt);
782 
788 const MultiVector getDiagonal(const LinearOp & op,const DiagonalType & dt);
789 
796 std::string getDiagonalName(const DiagonalType & dt);
797 
806 DiagonalType getDiagonalType(std::string name);
807 
808 LinearOp probe(Teuchos::RCP<const Epetra_CrsGraph> &G, const LinearOp & Op);
809 
812 double norm_1(const MultiVector & v,std::size_t col);
813 
816 double norm_2(const MultiVector & v,std::size_t col);
817 
821 void clipLower(MultiVector & v,double lowerBound);
822 
826 void clipUpper(MultiVector & v,double upperBound);
827 
831 void replaceValue(MultiVector & v,double currentValue,double newValue);
832 
835 void columnAverages(const MultiVector & v,std::vector<double> & averages);
836 
839 double average(const MultiVector & v);
840 
841 } // end namespace Teko
842 
843 #ifdef _MSC_VER
844 #ifdef TEKO_DEFINED_MSC_EXTENSIONS
845 #undef _MSC_EXTENSIONS
846 #endif
847 #endif
848 
849 #endif
LinearOp adjoint(ModifiableLinearOp &a)
Construct an implicit adjoint of the linear operators.
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.
Specifies that a block diagonal approximation is to be used.
Specifies that just the diagonal is used.
MultiVector deepcopy(const MultiVector &v)
Perform a deep copy of the vector.
int blockRowCount(const BlockedLinearOp &blo)
Get the row count in a block linear operator.
Specifies that row sum is used to form a diagonal.
void scale(const double alpha, MultiVector &x)
Scale a multivector by a constant.
BlockedLinearOp toBlockedLinearOp(LinearOp &clo)
Converts a LinearOp to a BlockedLinearOp.
void endBlockFill(BlockedLinearOp &blo)
Notify the blocked operator that the fill stage is completed.
MultiVector copyAndInit(const MultiVector &v, double scalar)
Perform a deep copy of the vector.
VectorSpace domainSpace(const LinearOp &lo)
Get the domain space of a linear operator.
void beginBlockFill(BlockedLinearOp &blo, int rowCnt, int colCnt)
Let the blocked operator know that you are going to set the sub blocks.
const BlockedMultiVector toBlockedMultiVector(const MultiVector &bmv)
Convert to a BlockedMultiVector from a MultiVector.
VectorSpace rangeSpace(const LinearOp &lo)
Get the range space of a linear operator.
LinearOp toLinearOp(BlockedLinearOp &blo)
Convert to a LinearOp from a BlockedLinearOp.
LinearOp zero(const VectorSpace &vs)
Build a square zero operator from a single vector space.
MultiVector datacopy(const MultiVector &src, MultiVector &dst)
Copy the contents of a multivector to a destination vector.
MultiVector getBlock(int i, const BlockedMultiVector &bmv)
Get the ith block from a BlockedMultiVector object.
For user convenience, if Teko recieves this value, exceptions will be thrown.
DiagonalType
Type describing the type of diagonal to construct.
int blockColCount(const BlockedLinearOp &blo)
Get the column count in a block linear operator.
BlockedLinearOp createBlockedOp()
Build a new blocked linear operator.
void setBlock(int i, int j, BlockedLinearOp &blo, const LinearOp &lo)
Set the i,j block in a BlockedLinearOp object.
Specifies that the diagonal entry is .