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");
116 RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
117 TEUCHOS_TEST_FOR_EXCEPTION(bA == Teuchos::null,
Exceptions::BadCast,
"MueLu::SimpleSmoother::Setup: input matrix A is not of type BlockedCrsMatrix! error.");
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);
157 RCP<BlockedVector> bdiagFinv = Teuchos::rcp_dynamic_cast<BlockedVector>(diagFinv_);
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);
166 RCP<const FactoryManagerBase> velpredictFactManager = FactManager_.at(0);
168 velPredictSmoo_ = currentLevel.
Get<RCP<SmootherBase>>(
"PreSmoother", velpredictFactManager->GetFactory(
"Smoother").get());
171 RCP<const FactoryManagerBase> schurFactManager = FactManager_.at(1);
173 schurCompSmoo_ = currentLevel.
Get<RCP<SmootherBase>>(
"PreSmoother", schurFactManager->GetFactory(
"Smoother").get());
182 "MueLu::SimpleSmoother::Apply(): Setup() has not been called");
185 RCP<MultiVector> rcpDebugX = Teuchos::rcpFromRef(X);
186 RCP<const MultiVector> rcpDebugB = Teuchos::rcpFromRef(B);
187 RCP<BlockedMultiVector> rcpBDebugX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpDebugX);
188 RCP<const BlockedMultiVector> rcpBDebugB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpDebugB);
189 if(rcpBDebugB.is_null() ==
false) {
194 if(rcpBDebugX.is_null() ==
false) {
201 const SC zero = Teuchos::ScalarTraits<SC>::zero();
202 const SC one = Teuchos::ScalarTraits<SC>::one();
210 bool bRangeThyraMode = rangeMapExtractor_->getThyraMode();
211 bool bDomainThyraMode = domainMapExtractor_->getThyraMode();
216 RCP<MultiVector> rcpX = Teuchos::rcpFromRef(X);
217 RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
220 bool bCopyResultX =
false;
221 bool bReorderX =
false;
222 bool bReorderB =
false;
223 RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
225 RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
226 RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
229 RCP<Xpetra::ReorderedBlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> rbA =
230 Teuchos::rcp_dynamic_cast<Xpetra::ReorderedBlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(bA);
232 if (rbA.is_null() ==
false) {
237 if (bX.is_null() ==
true) {
238 RCP<MultiVector> vectorWithBlockedMap = Teuchos::rcp(
new BlockedMultiVector(rbA->getBlockedCrsMatrix()->getBlockedDomainMap(), rcpX));
239 rcpX.swap(vectorWithBlockedMap);
245 if (bB.is_null() ==
true) {
246 RCP<const MultiVector> vectorWithBlockedMap = Teuchos::rcp(
new BlockedMultiVector(rbA->getBlockedCrsMatrix()->getBlockedRangeMap(), rcpB));
247 rcpB.swap(vectorWithBlockedMap);
252 if (bX.is_null() ==
true) {
253 RCP<MultiVector> vectorWithBlockedMap = Teuchos::rcp(
new BlockedMultiVector(bA->getBlockedDomainMap(), rcpX));
254 rcpX.swap(vectorWithBlockedMap);
258 if (bB.is_null() ==
true) {
259 RCP<const MultiVector> vectorWithBlockedMap = Teuchos::rcp(
new BlockedMultiVector(bA->getBlockedRangeMap(), rcpB));
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) {
270 Teuchos::RCP<const Xpetra::BlockReorderManager> brm = rbA->getBlockReorderManager();
273 if (bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps() || bReorderX) {
275 Teuchos::RCP<MultiVector> reorderedBlockedVector = buildReorderedBlockedMultiVector(brm, bX);
276 rcpX.swap(reorderedBlockedVector);
279 if (bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps() || bReorderB) {
281 Teuchos::RCP<const MultiVector> reorderedBlockedVector = buildReorderedBlockedMultiVector(brm, bB);
282 rcpB.swap(reorderedBlockedVector);
290 RCP<MultiVector> residual = MultiVectorFactory::Build(rcpB->getMap(), rcpB->getNumVectors());
291 RCP<BlockedMultiVector> bresidual = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(residual);
292 RCP<MultiVector> r1 = bresidual->getMultiVector(0, bRangeThyraMode);
293 RCP<MultiVector> r2 = bresidual->getMultiVector(1, bRangeThyraMode);
296 RCP<MultiVector> xtilde = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
297 RCP<BlockedMultiVector> bxtilde = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xtilde);
298 RCP<MultiVector> xtilde1 = bxtilde->getMultiVector(0, bDomainThyraMode);
299 RCP<MultiVector> xtilde2 = bxtilde->getMultiVector(1, bDomainThyraMode);
302 RCP<MultiVector> xhat = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
303 RCP<BlockedMultiVector> bxhat = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xhat);
304 RCP<MultiVector> xhat1 = bxhat->getMultiVector(0, bDomainThyraMode);
305 RCP<MultiVector> xhat2 = bxhat->getMultiVector(1, bDomainThyraMode);
310 residual->update(one, *rcpB, zero);
311 if (InitialGuessIsZero ==
false || run > 0)
312 A_->apply(*rcpX, *residual, Teuchos::NO_TRANS, -one, one);
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) {
346 RCP<const MultiVector> Xmerged = bX->Merge();
347 X.update(one, *Xmerged, zero);