84 this->GetOStream(
Warnings0) <<
"MueLu::BreaessSarazinSmoother::Setup(): Setup() has already been called";
87 A_ = Factory::Get<RCP<Matrix> >(currentLevel,
"A");
88 RCP<BlockedCrsMatrix> bA = rcp_dynamic_cast<BlockedCrsMatrix>(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);
117 RCP<BlockedVector> bD = Teuchos::rcp_dynamic_cast<BlockedVector>(D_);
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());
137 "MueLu::BraessSarazinSmoother::Apply(): Setup() has not been called");
139 RCP<MultiVector> rcpX = rcpFromRef(X);
140 RCP<const MultiVector> rcpB = rcpFromRef(B);
143 bool bCopyResultX =
false;
144 bool bReorderX =
false;
145 bool bReorderB =
false;
146 RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
148 RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
149 RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
152 RCP<Xpetra::ReorderedBlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > rbA =
153 Teuchos::rcp_dynamic_cast<Xpetra::ReorderedBlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(bA);
155 if (rbA.is_null() ==
false) {
160 if (bX.is_null() ==
true) {
161 RCP<MultiVector> vectorWithBlockedMap = Teuchos::rcp(
new BlockedMultiVector(rbA->getBlockedCrsMatrix()->getBlockedDomainMap(), rcpX));
162 rcpX.swap(vectorWithBlockedMap);
168 if (bB.is_null() ==
true) {
169 RCP<const MultiVector> vectorWithBlockedMap = Teuchos::rcp(
new BlockedMultiVector(rbA->getBlockedCrsMatrix()->getBlockedRangeMap(), rcpB));
170 rcpB.swap(vectorWithBlockedMap);
175 if (bX.is_null() ==
true) {
176 RCP<MultiVector> vectorWithBlockedMap = Teuchos::rcp(
new BlockedMultiVector(bA->getBlockedDomainMap(), rcpX));
177 rcpX.swap(vectorWithBlockedMap);
181 if (bB.is_null() ==
true) {
182 RCP<const MultiVector> vectorWithBlockedMap = Teuchos::rcp(
new BlockedMultiVector(bA->getBlockedRangeMap(), rcpB));
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) {
193 Teuchos::RCP<const Xpetra::BlockReorderManager> brm = rbA->getBlockReorderManager();
196 if (bX->getBlockedMap()->getNumMaps() != bA->getDomainMapExtractor()->NumMaps() || bReorderX) {
198 Teuchos::RCP<MultiVector> reorderedBlockedVector = buildReorderedBlockedMultiVector(brm, bX);
199 rcpX.swap(reorderedBlockedVector);
202 if (bB->getBlockedMap()->getNumMaps() != bA->getRangeMapExtractor()->NumMaps() || bReorderB) {
204 Teuchos::RCP<const MultiVector> reorderedBlockedVector = buildReorderedBlockedMultiVector(brm, bB);
205 rcpB.swap(reorderedBlockedVector);
212 bool bRangeThyraMode = rangeMapExtractor_->getThyraMode();
213 bool bDomainThyraMode = domainMapExtractor_->getThyraMode();
215 RCP<MultiVector> deltaX = MultiVectorFactory::Build(rcpX->getMap(), rcpX->getNumVectors());
216 RCP<BlockedMultiVector> bdeltaX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(deltaX);
217 RCP<MultiVector> deltaX0 = bdeltaX->getMultiVector(0, bDomainThyraMode);
218 RCP<MultiVector> deltaX1 = bdeltaX->getMultiVector(1, bDomainThyraMode);
220 RCP<MultiVector> Rtmp = rangeMapExtractor_->getVector(1, rcpB->getNumVectors(), bRangeThyraMode);
222 typedef Teuchos::ScalarTraits<SC> STS;
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) {
259 ArrayRCP<SC> Sdiag = diagSVector->getDataNonConst(0);
260 ArrayRCP<SC> deltaX1data = deltaX1->getDataNonConst(0);
261 ArrayRCP<SC> Rtmpdata = Rtmp->getDataNonConst(0);
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) {
294 RCP<MultiVector> Xmerged = bX->Merge();
295 X.update(one, *Xmerged, zero);