10 #ifndef MUELU_SIMPLESMOOTHER_DEF_HPP_
11 #define MUELU_SIMPLESMOOTHER_DEF_HPP_
13 #include "Teuchos_ArrayViewDecl.hpp"
19 #include <Xpetra_CrsMatrixWrap.hpp>
21 #include <Xpetra_MultiVectorFactory.hpp>
27 #include "MueLu_Utilities.hpp"
29 #include "MueLu_HierarchyUtils.hpp"
33 #include "MueLu_SchurComplementFactory.hpp"
34 #include "MueLu_FactoryManager.hpp"
38 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
41 , A_(Teuchos::null) {}
43 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
46 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
51 validParamList->
set<
Scalar>(
"Damping factor", 1.0,
"Damping/Scaling factor in SIMPLE");
52 validParamList->
set<
LocalOrdinal>(
"Sweeps", 1,
"Number of SIMPLE sweeps (default = 1)");
53 validParamList->
set<
bool>(
"UseSIMPLEC",
false,
"Use SIMPLEC instead of SIMPLE (default = false)");
55 return validParamList;
59 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
63 size_t myPos = Teuchos::as<size_t>(pos);
65 if (myPos < FactManager_.size()) {
67 FactManager_.at(myPos) = FactManager;
68 }
else if (myPos == FactManager_.size()) {
70 FactManager_.push_back(FactManager);
73 *out <<
"Warning: cannot add new FactoryManager at proper position " << pos <<
". The FactoryManager is just appended to the end. Check this!" << std::endl;
76 FactManager_.push_back(FactManager);
80 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
82 AddFactoryManager(FactManager, 0);
85 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
87 AddFactoryManager(FactManager, 1);
90 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
92 currentLevel.
DeclareInput(
"A", this->GetFactory(
"A").
get());
94 TEUCHOS_TEST_FOR_EXCEPTION(FactManager_.size() != 2,
Exceptions::RuntimeError,
"MueLu::SimpleSmoother::DeclareInput: You have to declare two FactoryManagers with a \"Smoother\" object: One for predicting the primary variable and one for the SchurComplement system. The smoother for the SchurComplement system needs a SchurComplementFactory as input for variable \"A\". make sure that you use the same proper damping factors for omega both in the SchurComplementFactory and in the SIMPLE smoother!");
97 std::vector<Teuchos::RCP<const FactoryManagerBase>>::const_iterator it;
98 for (it = FactManager_.begin(); it != FactManager_.end(); ++it) {
102 currentLevel.
DeclareInput(
"PreSmoother", (*it)->GetFactory(
"Smoother").get());
106 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
108 FactoryMonitor m(*
this,
"Setup blocked SIMPLE Smoother", currentLevel);
111 this->GetOStream(
Warnings0) <<
"MueLu::SimpleSmoother::Setup(): Setup() has already been called";
114 A_ = Factory::Get<RCP<Matrix>>(currentLevel,
"A");
120 rangeMapExtractor_ = bA->getRangeMapExtractor();
121 domainMapExtractor_ = bA->getDomainMapExtractor();
124 F_ = bA->getMatrix(0, 0);
125 G_ = bA->getMatrix(0, 1);
126 D_ = bA->getMatrix(1, 0);
127 Z_ = bA->getMatrix(1, 1);
130 bool bSIMPLEC = pL.
get<
bool>(
"UseSIMPLEC");
134 RCP<Vector> diagFVector = VectorFactory::Build(F_->getRowMap());
136 F_->getLocalDiagCopy(*diagFVector);
158 if (bdiagFinv.
is_null() ==
false && bdiagFinv->getBlockedMap()->getNumMaps() == 1) {
159 RCP<Vector> nestedVec = bdiagFinv->getMultiVector(0, bdiagFinv->getBlockedMap()->getThyraMode())->getVectorNonConst(0);
160 diagFinv_.
swap(nestedVec);
179 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
182 "MueLu::SimpleSmoother::Apply(): Setup() has not been called");
189 if(rcpBDebugB.is_null() ==
false) {
194 if(rcpBDebugX.
is_null() ==
false) {
210 bool bRangeThyraMode = rangeMapExtractor_->getThyraMode();
211 bool bDomainThyraMode = domainMapExtractor_->getThyraMode();
220 bool bCopyResultX =
false;
221 bool bReorderX =
false;
222 bool bReorderB =
false;
232 if (rbA.is_null() ==
false) {
237 if (bX.is_null() ==
true) {
239 rcpX.
swap(vectorWithBlockedMap);
245 if (bB.is_null() ==
true) {
247 rcpB.
swap(vectorWithBlockedMap);
252 if (bX.is_null() ==
true) {
254 rcpX.
swap(vectorWithBlockedMap);
258 if (bB.is_null() ==
true) {
260 rcpB.
swap(vectorWithBlockedMap);
265 bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
266 bB = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(rcpB);
269 if (rbA.is_null() ==
false) {
273 if (bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps() || bReorderX) {
276 rcpX.
swap(reorderedBlockedVector);
279 if (bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps() || bReorderB) {
282 rcpB.
swap(reorderedBlockedVector);
296 RCP<MultiVector> xtilde = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
302 RCP<MultiVector> xhat = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
310 residual->update(one, *rcpB, zero);
311 if (InitialGuessIsZero ==
false || run > 0)
316 xtilde1->putScalar(zero);
317 xtilde2->putScalar(zero);
318 velPredictSmoo_->Apply(*xtilde1, *r1);
322 RCP<MultiVector> schurCompRHS = rangeMapExtractor_->getVector(1, rcpB->getNumVectors(), bRangeThyraMode);
323 D_->apply(*xtilde1, *schurCompRHS);
325 schurCompRHS->update(one, *r2, -one);
329 schurCompSmoo_->Apply(*xtilde2, *schurCompRHS);
333 xhat2->update(omega, *xtilde2, zero);
336 RCP<MultiVector> xhat1_temp = domainMapExtractor_->getVector(0, rcpX->getNumVectors(), bDomainThyraMode);
337 G_->apply(*xhat2, *xhat1_temp);
339 xhat1->elementWiseMultiply(one , *diagFinv_, *xhat1_temp, zero);
340 xhat1->update(one, *xtilde1, -one);
342 rcpX->update(one, *bxhat, one);
345 if (bCopyResultX ==
true) {
347 X.update(one, *Xmerged, zero);
351 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
357 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
359 std::ostringstream out;
361 out <<
"{type = " << type_ <<
"}";
365 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
370 out0 <<
"Prec. type: " << type_ << std::endl;
373 if (verbLevel &
Debug) {
378 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
Important warning messages (one line)
void SetSchurCompFactoryManager(RCP< FactoryManager > FactManager)
virtual const Teuchos::ParameterList & GetParameterList() const
Exception indicating invalid cast attempted.
void AddFactoryManager(RCP< const FactoryManagerBase > FactManager, int pos)
Add a factory manager at a specific position.
MueLu::DefaultLocalOrdinal LocalOrdinal
SimpleSmoother()
Constructor.
T & get(const std::string &name, T def_value)
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void Setup(Level ¤tLevel)
Setup routine.
void swap(RCP< T > &r_ptr)
Print additional debugging information.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void DeclareInput(Level ¤tLevel) const
Input.
void SetVelocityPredictionFactoryManager(RCP< FactoryManager > FactManager)
virtual ~SimpleSmoother()
Destructor.
RCP< SmootherPrototype > Copy() const
virtual const RCP< const FactoryBase > GetFactory(const std::string &varName) const =0
Get.
RCP< const ParameterList > GetValidParameterList() const
Input.
std::string description() const
Return a simple one-line description of this object.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultScalar Scalar
Class that holds all level-specific information.
bool IsSetup() const
Get the state of a smoother prototype.
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
void Apply(MultiVector &X, MultiVector const &B, bool InitialGuessIsZero=false) const
Apply the Braess Sarazin smoother.
void residual(const Operator< SC, LO, GO, NO > &Aop, const MultiVector< SC, LO, GO, NO > &X_in, const MultiVector< SC, LO, GO, NO > &B_in, MultiVector< SC, LO, GO, NO > &R_in)
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.
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()
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
virtual std::string description() const
Return a simple one-line description of this object.
SIMPLE smoother for 2x2 block matrices.
std::string toString(const T &t)