10 #ifndef MUELU_BRAESSSARAZINSMOOTHER_DEF_HPP_ 
   11 #define MUELU_BRAESSSARAZINSMOOTHER_DEF_HPP_ 
   13 #include <Teuchos_ArrayViewDecl.hpp> 
   20 #include <Xpetra_MultiVectorFactory.hpp> 
   26 #include "MueLu_Utilities.hpp" 
   28 #include "MueLu_HierarchyUtils.hpp" 
   31 #include "MueLu_FactoryManager.hpp" 
   35 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   38   FactManager_ = FactManager;
 
   41 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   49   validParamList->
set<
bool>(
"lumping", 
false,
 
   50                             "Use lumping to construct diag(A(0,0)), " 
   51                             "i.e. use row sum of the abs values on the diagonal as approximation of A00 (and A00^{-1})");
 
   52   validParamList->
set<
SC>(
"Damping factor", one, 
"Damping/Scaling factor in BraessSarazin (usually has to be chosen > 1, default = 1.0)");
 
   53   validParamList->
set<
LO>(
"Sweeps", 1, 
"Number of BraessSarazin sweeps (default = 1)");
 
   54   validParamList->
set<
bool>(
"q2q1 mode", 
false, 
"Run in the mode matching Q2Q1 matlab code");
 
   56   return validParamList;
 
   59 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   61   this->Input(currentLevel, 
"A");
 
   64                              "MueLu::BraessSarazinSmoother::DeclareInput: FactManager_ must not be null! " 
   65                              "Introduce a FactoryManager for the SchurComplement equation.");
 
   72     currentLevel.
DeclareInput(
"PreSmoother", FactManager_->GetFactory(
"Smoother").get());
 
   75     currentLevel.
DeclareInput(
"A", FactManager_->GetFactory(
"A").get());
 
   79 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
   84     this->GetOStream(
Warnings0) << 
"MueLu::BreaessSarazinSmoother::Setup(): Setup() has already been called";
 
   87   A_                       = Factory::Get<RCP<Matrix> >(currentLevel, 
"A");
 
   90                              "MueLu::BraessSarazinSmoother::Setup: input matrix A is not of type BlockedCrsMatrix! error.");
 
   93   rangeMapExtractor_  = bA->getRangeMapExtractor();
 
   94   domainMapExtractor_ = bA->getDomainMapExtractor();
 
   97   A00_ = bA->getMatrix(0, 0);
 
   98   A01_ = bA->getMatrix(0, 1);
 
   99   A10_ = bA->getMatrix(1, 0);
 
  100   A11_ = bA->getMatrix(1, 1);
 
  103   SC omega                = pL.
get<
SC>(
"Damping factor");
 
  107   RCP<Vector> diagFVector = VectorFactory::Build(A00_->getRowMap());
 
  108   if (pL.
get<
bool>(
"lumping") == 
false) {
 
  109     A00_->getLocalDiagCopy(*diagFVector);  
 
  113   diagFVector->scale(omega);
 
  118   if (bD.
is_null() == 
false && bD->getBlockedMap()->getNumMaps() == 1) {
 
  119     RCP<Vector> nestedVec = bD->getMultiVector(0, bD->getBlockedMap()->getThyraMode())->getVectorNonConst(0);
 
  127     smoo_ = currentLevel.Get<
RCP<SmootherBase> >(
"PreSmoother", FactManager_->GetFactory(
"Smoother").get());
 
  128     S_    = currentLevel.Get<
RCP<Matrix> >(
"A", FactManager_->GetFactory(
"A").get());
 
  134 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  137                              "MueLu::BraessSarazinSmoother::Apply(): Setup() has not been called");
 
  143   bool bCopyResultX        = 
false;
 
  144   bool bReorderX           = 
false;
 
  145   bool bReorderB           = 
false;
 
  155   if (rbA.is_null() == 
false) {
 
  160     if (bX.is_null() == 
true) {
 
  162       rcpX.
swap(vectorWithBlockedMap);
 
  168     if (bB.is_null() == 
true) {
 
  170       rcpB.
swap(vectorWithBlockedMap);
 
  175     if (bX.is_null() == 
true) {
 
  177       rcpX.
swap(vectorWithBlockedMap);
 
  181     if (bB.is_null() == 
true) {
 
  183       rcpB.
swap(vectorWithBlockedMap);
 
  188   bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
 
  189   bB = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(rcpB);
 
  192   if (rbA.is_null() == 
false) {
 
  196     if (bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps() || bReorderX) {
 
  199       rcpX.
swap(reorderedBlockedVector);
 
  202     if (bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps() || bReorderB) {
 
  205       rcpB.
swap(reorderedBlockedVector);
 
  212   bool bRangeThyraMode  = rangeMapExtractor_->getThyraMode();
 
  213   bool bDomainThyraMode = domainMapExtractor_->getThyraMode();
 
  215   RCP<MultiVector> deltaX         = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
 
  220   RCP<MultiVector> Rtmp = rangeMapExtractor_->getVector(1, rcpB->getNumVectors(), bRangeThyraMode);
 
  223   SC one = STS::one(), zero = STS::zero();
 
  227   LO nSweeps              = pL.
get<
LO>(
"Sweeps");
 
  230   if (InitialGuessIsZero) {
 
  231     R = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());
 
  232     R->update(one, *rcpB, zero);
 
  238   RCP<Vector> diagSVector = VectorFactory::Build(S_->getRowMap());
 
  239   S_->getLocalDiagCopy(*diagSVector);
 
  241   for (
LO run = 0; run < nSweeps; ++run) {
 
  245     RCP<MultiVector> R0 = rangeMapExtractor_->ExtractVector(R, 0, bRangeThyraMode);
 
  246     RCP<MultiVector> R1 = rangeMapExtractor_->ExtractVector(R, 1, bRangeThyraMode);
 
  249     deltaX0->putScalar(zero);
 
  250     deltaX0->elementWiseMultiply(one, *D_, *R0, zero);  
 
  251     A10_->apply(*deltaX0, *Rtmp);                       
 
  252     Rtmp->update(one, *R1, -one);                       
 
  254     if (!pL.
get<
bool>(
"q2q1 mode")) {
 
  255       deltaX1->putScalar(zero);
 
  258       if (Teuchos::rcp_dynamic_cast<BlockedVector>(diagSVector) == Teuchos::null) {
 
  262         for (
GO row = 0; row < deltaX1data.
size(); row++)
 
  263           deltaX1data[row] = Teuchos::as<SC>(1.1) * Rtmpdata[row] / Sdiag[row];
 
  269     smoo_->Apply(*deltaX1, *Rtmp);
 
  272     deltaX0->putScalar(zero);         
 
  273     A01_->apply(*deltaX1, *deltaX0);  
 
  274     deltaX0->update(one, *R0, -one);  
 
  276     deltaX0->elementWiseMultiply(one, *D_, *R0, zero);  
 
  278     RCP<MultiVector> X0 = domainMapExtractor_->ExtractVector(rcpX, 0, bDomainThyraMode);
 
  279     RCP<MultiVector> X1 = domainMapExtractor_->ExtractVector(rcpX, 1, bDomainThyraMode);
 
  282     X0->update(one, *deltaX0, one);
 
  283     X1->update(one, *deltaX1, one);
 
  285     domainMapExtractor_->InsertVector(X0, 0, rcpX, bDomainThyraMode);
 
  286     domainMapExtractor_->InsertVector(X1, 1, rcpX, bDomainThyraMode);
 
  288     if (run < nSweeps - 1) {
 
  293   if (bCopyResultX == 
true) {
 
  295     X.update(one, *Xmerged, zero);
 
  299 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  305 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  308   std::ostringstream out;
 
  310   out << 
"{type = " << type_ << 
"}";
 
  314 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
  319     out0 << 
"Prec. type: " << type_ <<  std::endl;
 
  322   if (verbLevel & 
Debug) {
 
  327 template <
class Scalar, 
class LocalOrdinal, 
class GlobalOrdinal, 
class Node>
 
Important warning messages (one line) 
 
virtual const Teuchos::ParameterList & GetParameterList() const 
 
Exception indicating invalid cast attempted. 
 
BraessSarazin smoother for 2x2 block matrices. 
 
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const 
Print the object with some verbosity level to an FancyOStream object. 
 
T & get(const std::string &name, T def_value)
 
Timer to be used in factories. Similar to Monitor but with additional timers. 
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
void swap(RCP< T > &r_ptr)
 
Print additional debugging information. 
 
RCP< SmootherPrototype > Copy() const 
 
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
 
void DeclareInput(Level ¤tLevel) const 
Input. 
 
static RCP< MultiVector > Residual(const Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, const MultiVector &X, const MultiVector &RHS)
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
 
size_t getNodeSmootherComplexity() const 
Get a rough estimate of cost per iteration. 
 
Class that holds all level-specific information. 
 
bool IsSetup() const 
Get the state of a smoother prototype. 
 
RCP< const ParameterList > GetValidParameterList() const 
Input. 
 
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects. 
 
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager, int pos=0)
Add a factory manager for BraessSarazin internal SchurComplement handling. 
 
void Setup(Level ¤tLevel)
Setup routine. 
 
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const 
Apply the Braess Sarazin smoother. 
 
Exception throws to report errors in the internal logical of the program. 
 
#define MUELU_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
An exception safe way to call the method 'Level::SetFactoryManager()'. 
 
Teuchos::RCP< const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > buildReorderedBlockedMultiVector(Teuchos::RCP< const Xpetra::BlockReorderManager > brm, Teuchos::RCP< const Xpetra::BlockedMultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > bvec)
 
static Teuchos::RCP< Vector > GetInverse(Teuchos::RCP< const Vector > v, Magnitude tol=Teuchos::ScalarTraits< Scalar >::eps()*100, Scalar valReplacement=Teuchos::ScalarTraits< Scalar >::zero())
Return vector containing inverse of input vector. 
 
std::string description() const 
Return a simple one-line description of this object. 
 
static Teuchos::RCP< Vector > GetLumpedMatrixDiagonal(Matrix const &A, const bool doReciprocal=false, Magnitude tol=Teuchos::ScalarTraits< Scalar >::magnitude(Teuchos::ScalarTraits< Scalar >::zero()), Scalar valReplacement=Teuchos::ScalarTraits< Scalar >::zero(), const bool replaceSingleEntryRowWithZero=false, const bool useAverageAbsDiagVal=false)
Extract Matrix Diagonal of lumped matrix. 
 
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput() 
 
virtual std::string description() const 
Return a simple one-line description of this object. 
 
std::string toString(const T &t)