103 const std::string prefix =
"MueLu::SaPFactory(" + levelIDs +
"): ";
105 typedef typename Teuchos::ScalarTraits<SC>::coordinateType Coordinate;
106 typedef typename Teuchos::ScalarTraits<SC>::magnitudeType MT;
111 RCP<const FactoryBase> initialPFact =
GetFactory(
"P");
112 if (initialPFact == Teuchos::null) {
119 RCP<Matrix> Ptent = coarseLevel.
Get<RCP<Matrix>>(
"P", initialPFact.get());
123 if (Ptent == Teuchos::null) {
124 finalP = Teuchos::null;
125 Set(coarseLevel,
"P", finalP);
137 RCP<ParameterList> APparams;
138 if (pL.isSublist(
"matrixmatrix: kernel params"))
139 APparams = rcp(
new ParameterList(pL.sublist(
"matrixmatrix: kernel params")));
141 APparams = rcp(
new ParameterList);
142 if (coarseLevel.
IsAvailable(
"AP reuse data",
this)) {
145 APparams = coarseLevel.
Get<RCP<ParameterList>>(
"AP reuse data",
this);
147 if (APparams->isParameter(
"graph"))
148 finalP = APparams->get<RCP<Matrix>>(
"graph");
151 APparams->set(
"compute global constants: temporaries", APparams->get(
"compute global constants: temporaries",
false));
152 APparams->set(
"compute global constants", APparams->get(
"compute global constants",
false));
154 const SC dampingFactor = as<SC>(pL.get<
double>(
"sa: damping factor"));
155 const LO maxEigenIterations = as<LO>(pL.get<
int>(
"sa: eigenvalue estimate num iterations"));
156 const bool estimateMaxEigen = pL.get<
bool>(
"sa: calculate eigenvalue estimate");
157 const bool useAbsValueRowSum = pL.get<
bool>(
"sa: use rowsumabs diagonal scaling");
158 const bool doQRStep = pL.get<
bool>(
"tentative: calculate qr");
159 const bool enforceConstraints = pL.get<
bool>(
"sa: enforce constraints");
160 const MT userDefinedMaxEigen = as<MT>(pL.get<
double>(
"sa: max eigenvalue"));
161 double dTol = pL.get<
double>(
"sa: diagonal replacement tolerance");
162 double dTol_rs = pL.get<
double>(
"sa: rowsumabs diagonal replacement tolerance");
163 const MT diagonalReplacementTolerance = (dTol == as<double>(-1) ? Teuchos::ScalarTraits<MT>::eps() * 100 : as<MT>(pL.get<
double>(
"sa: diagonal replacement tolerance")));
164 const MT diagonalReplacementTolerance_rs = (dTol_rs == as<double>(-1) ? Teuchos::ScalarTraits<MT>::eps() * 100 : as<MT>(pL.get<
double>(
"sa: rowsumabs diagonal replacement tolerance")));
166 const SC diagonalReplacementValue = as<SC>(pL.get<
double>(
"sa: rowsumabs diagonal replacement value"));
167 const bool replaceSingleEntryRowWithZero = pL.get<
bool>(
"sa: rowsumabs replace single entry row with zero");
168 const bool useAutomaticDiagTol = pL.get<
bool>(
"sa: rowsumabs use automatic diagonal tolerance");
172 "MueLu::TentativePFactory::MakeTentative: cannot use 'enforce constraints' and 'calculate qr' at the same time");
175 const bool specialMaxwell1Smoothing = pL.get<
bool>(
"sa: maxwell1 smoothing");
177 if (!specialMaxwell1Smoothing) {
178 if (dampingFactor != Teuchos::ScalarTraits<SC>::zero()) {
180 Teuchos::RCP<Vector> invDiag;
181 if (userDefinedMaxEigen == -1.) {
183 lambdaMax = A->GetMaxEigenvalueEstimate();
184 if (lambdaMax == -Teuchos::ScalarTraits<SC>::one() || estimateMaxEigen) {
185 GetOStream(
Statistics1) <<
"Calculating max eigenvalue estimate now (max iters = " << maxEigenIterations << ((useAbsValueRowSum) ?
", use rowSumAbs diagonal)" :
", use point diagonal)") << std::endl;
186 Coordinate stopTol = 1e-4;
187 if (useAbsValueRowSum) {
188 const bool returnReciprocal =
true;
190 diagonalReplacementTolerance_rs,
191 diagonalReplacementValue,
192 replaceSingleEntryRowWithZero,
193 useAutomaticDiagTol);
195 "SaPFactory: eigenvalue estimate: diagonal reciprocal is null.");
199 A->SetMaxEigenvalueEstimate(lambdaMax);
204 lambdaMax = userDefinedMaxEigen;
205 A->SetMaxEigenvalueEstimate(lambdaMax);
207 MT omega = Teuchos::ScalarTraits<SC>::magnitude(dampingFactor) / Teuchos::ScalarTraits<SC>::magnitude(lambdaMax);
208 GetOStream(
Statistics1) <<
"Prolongator damping factor = " << omega <<
" (|" << dampingFactor <<
" / " << lambdaMax <<
"|)" << std::endl;
212 if (!useAbsValueRowSum)
214 else if (invDiag == Teuchos::null) {
216 const bool returnReciprocal =
true;
218 diagonalReplacementTolerance_rs,
219 diagonalReplacementValue,
220 replaceSingleEntryRowWithZero,
221 useAutomaticDiagTol);
222 TEUCHOS_TEST_FOR_EXCEPTION(invDiag.is_null(),
Exceptions::RuntimeError,
"SaPFactory: diagonal reciprocal is null.");
225 TEUCHOS_TEST_FOR_EXCEPTION(!std::isfinite(omega),
Exceptions::RuntimeError,
"Prolongator damping factor needs to be finite.");
230 finalP =
MueLu::IteratorOps<SC, LO, GO, NO>::Jacobi(omega, *invDiag, *A, *Ptent, finalP,
GetOStream(
Statistics2), std::string(
"MueLu::SaP-") +
toString(coarseLevel.
GetLevelID()), APparams);
231 if (enforceConstraints) {
232 if (!pL.get<
bool>(
"use kokkos refactor")) {
233 if (A->GetFixedBlockSize() == 1)
257 const SC nodalDampingFactor = as<SC>(pL.get<
double>(
"sa: nodal damping factor"));
259 const bool nodalAndEdgeSmoothing = ((nodalDampingFactor != Teuchos::ScalarTraits<SC>::zero()) && (fineLevel.
Get<RCP<Matrix>>(
"NodeMatrix")->GetMaxEigenvalueEstimate() != -Teuchos::ScalarTraits<SC>::one()));
260 const bool edgeSmoothing = (dampingFactor != Teuchos::ScalarTraits<SC>::zero());
262 RCP<Matrix> P_afterNodalAndEdgeSmoothing;
263 if (nodalAndEdgeSmoothing) {
264 auto D0 = fineLevel.
Get<RCP<Matrix>>(
"D0");
265 auto NodeMatrix = fineLevel.
Get<RCP<Matrix>>(
"NodeMatrix");
267 auto lambdaMaxNodal = NodeMatrix->GetMaxEigenvalueEstimate();
268 MT beta = Teuchos::ScalarTraits<SC>::magnitude(nodalDampingFactor) / Teuchos::ScalarTraits<SC>::magnitude(lambdaMaxNodal);
269 GetOStream(
Statistics1) <<
"Maxwell1 prolongator nodal damping factor = " << beta <<
" (|" << nodalDampingFactor <<
" / " << lambdaMaxNodal <<
"|)" << std::endl;
270 TEUCHOS_TEST_FOR_EXCEPTION(lambdaMaxNodal == -Teuchos::ScalarTraits<SC>::one(),
Exceptions::RuntimeError,
"Prolongator damping factor obtained from NodeMatrix is -1.")
272 TEUCHOS_TEST_FOR_EXCEPTION(!std::isfinite(beta),
Exceptions::RuntimeError,
"Prolongator damping factor needs to be finite.");
276 P_afterNodalAndEdgeSmoothing =
JacobiMaxwell1(A, NodeMatrix, D0, Ptent, beta);
279 if (nodalDampingFactor == Teuchos::ScalarTraits<SC>::zero())
280 GetOStream(
Statistics1) <<
"Skipping nodal&edge smoothing step since nodal damping factor is zero\n";
281 else if (fineLevel.
Get<RCP<Matrix>>(
"NodeMatrix")->GetMaxEigenvalueEstimate() == -Teuchos::ScalarTraits<SC>::one())
282 GetOStream(
Warnings) <<
"Skipping nodal&edge smoothing step since NodeMatrix matrix has invalid eigenvalue estimate\n";
283 P_afterNodalAndEdgeSmoothing = Ptent;
287 RCP<Matrix> CurlCurl;
289 CurlCurl = fineLevel.
Get<RCP<Matrix>>(
"CurlCurl",
GetFactory(
"CurlCurl").get());
291 GetOStream(
Warnings0) <<
"Using edge matrix for edge-only prolongator smoothing. This generally violates the commuting relationship." << std::endl;
296 Teuchos::RCP<Vector> invDiag;
297 if (userDefinedMaxEigen == -1.) {
299 lambdaMax = CurlCurl->GetMaxEigenvalueEstimate();
300 if (lambdaMax == -Teuchos::ScalarTraits<SC>::one() || estimateMaxEigen) {
301 GetOStream(
Statistics1) <<
"Calculating max eigenvalue estimate now (max iters = " << maxEigenIterations << ((useAbsValueRowSum) ?
", use rowSumAbs diagonal)" :
", use point diagonal)") << std::endl;
302 Coordinate stopTol = 1e-4;
303 if (useAbsValueRowSum) {
304 const bool returnReciprocal =
true;
306 diagonalReplacementTolerance_rs,
307 diagonalReplacementValue,
308 replaceSingleEntryRowWithZero,
309 useAutomaticDiagTol);
311 "SaPFactory: eigenvalue estimate: diagonal reciprocal is null.");
314 lambdaMax =
Utilities::PowerMethod(*CurlCurl,
true, maxEigenIterations, stopTol, diagonalReplacementTolerance);
315 CurlCurl->SetMaxEigenvalueEstimate(lambdaMax);
320 lambdaMax = userDefinedMaxEigen;
321 CurlCurl->SetMaxEigenvalueEstimate(lambdaMax);
324 if (!useAbsValueRowSum)
326 else if (invDiag == Teuchos::null) {
328 const bool returnReciprocal =
true;
330 diagonalReplacementTolerance_rs,
331 diagonalReplacementValue,
332 replaceSingleEntryRowWithZero,
333 useAutomaticDiagTol);
334 TEUCHOS_TEST_FOR_EXCEPTION(invDiag.is_null(),
Exceptions::RuntimeError,
"SaPFactory: diagonal reciprocal is null.");
337 MT alpha = Teuchos::ScalarTraits<SC>::magnitude(dampingFactor) / Teuchos::ScalarTraits<SC>::magnitude(lambdaMax);
338 TEUCHOS_TEST_FOR_EXCEPTION(!std::isfinite(alpha),
Exceptions::RuntimeError,
"Prolongator damping factor needs to be finite.");
340 GetOStream(
Statistics1) <<
"Maxwell1 prolongator edge damping factor = " << alpha <<
" (|" << dampingFactor <<
" / " << lambdaMax <<
"|)" << std::endl;
345 finalP =
MueLu::IteratorOps<SC, LO, GO, NO>::Jacobi(alpha, *invDiag, *CurlCurl, *P_afterNodalAndEdgeSmoothing, finalP,
GetOStream(
Statistics2), std::string(
"MueLu::SaP-") +
toString(coarseLevel.
GetLevelID()), APparams);
349 finalP = P_afterNodalAndEdgeSmoothing;
357 if (!finalP.is_null()) {
358 std::ostringstream oss;
360 finalP->setObjectLabel(oss.str());
362 Set(coarseLevel,
"P", finalP);
364 APparams->set(
"graph", finalP);
365 Set(coarseLevel,
"AP reuse data", APparams);
368 if (Ptent->IsView(
"stridedMaps"))
369 finalP->CreateView(
"stridedMaps", Ptent);
377 std::ostringstream oss;
379 R->setObjectLabel(oss.str());
383 Set(coarseLevel,
"R", R);
386 if (Ptent->IsView(
"stridedMaps"))
387 R->CreateView(
"stridedMaps", Ptent,
true );
391 RCP<ParameterList> params = rcp(
new ParameterList());
392 params->set(
"printLoadBalancingInfo",
true);
393 params->set(
"printCommInfo",
true);
417 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
418 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
419 LO nPDEs = A->GetFixedBlockSize();
420 Teuchos::ArrayRCP<Scalar> ConstraintViolationSum(nPDEs);
421 Teuchos::ArrayRCP<Scalar> Rsum(nPDEs);
422 Teuchos::ArrayRCP<size_t> nPositive(nPDEs);
423 for (
size_t k = 0; k < (size_t)nPDEs; k++) ConstraintViolationSum[k] = zero;
424 for (
size_t k = 0; k < (size_t)nPDEs; k++) Rsum[k] = zero;
425 for (
size_t k = 0; k < (size_t)nPDEs; k++) nPositive[k] = 0;
427 for (
size_t i = 0; i < as<size_t>(P->getRowMap()->getLocalNumElements()); i++) {
428 Teuchos::ArrayView<const LocalOrdinal> indices;
429 Teuchos::ArrayView<const Scalar> vals1;
430 Teuchos::ArrayView<Scalar> vals;
431 P->getLocalRowView((LO)i, indices, vals1);
432 size_t nnz = indices.size();
433 if (nnz == 0)
continue;
435 vals = ArrayView<Scalar>(
const_cast<SC*
>(vals1.getRawPtr()), nnz);
437 bool checkRow =
true;
442 for (LO j = 0; j < indices.size(); j++) {
443 Rsum[j % nPDEs] += vals[j];
444 if (Teuchos::ScalarTraits<SC>::real(vals[j]) < Teuchos::ScalarTraits<SC>::real(zero)) {
445 ConstraintViolationSum[j % nPDEs] += vals[j];
448 if (Teuchos::ScalarTraits<SC>::real(vals[j]) != Teuchos::ScalarTraits<SC>::real(zero))
449 (nPositive[j % nPDEs])++;
451 if (Teuchos::ScalarTraits<SC>::real(vals[j]) > Teuchos::ScalarTraits<SC>::real(1.00001)) {
452 ConstraintViolationSum[j % nPDEs] += (vals[j] - one);
462 for (
size_t k = 0; k < (size_t)nPDEs; k++) {
463 if (Teuchos::ScalarTraits<SC>::real(Rsum[k]) < Teuchos::ScalarTraits<SC>::magnitude(zero)) {
464 ConstraintViolationSum[k] += (-Rsum[k]);
465 }
else if (Teuchos::ScalarTraits<SC>::real(Rsum[k]) > Teuchos::ScalarTraits<SC>::magnitude(1.00001)) {
466 ConstraintViolationSum[k] += (one - Rsum[k]);
471 for (
size_t k = 0; k < (size_t)nPDEs; k++) {
472 if (Teuchos::ScalarTraits<SC>::magnitude(ConstraintViolationSum[k]) != Teuchos::ScalarTraits<SC>::magnitude(zero))
477 for (LO j = 0; j < indices.size(); j++) {
478 if (Teuchos::ScalarTraits<SC>::real(vals[j]) > Teuchos::ScalarTraits<SC>::real(zero)) {
479 vals[j] += (ConstraintViolationSum[j % nPDEs] / (as<Scalar>(nPositive[j % nPDEs])));
482 for (
size_t k = 0; k < (size_t)nPDEs; k++) ConstraintViolationSum[k] = zero;
484 for (
size_t k = 0; k < (size_t)nPDEs; k++) Rsum[k] = zero;
485 for (
size_t k = 0; k < (size_t)nPDEs; k++) nPositive[k] = 0;
643 Scalar notFlippedLeftBound, notFlippedRghtBound, aBigNumber, *origSorted;
644 Scalar rowSumDeviation, temp, *fixedSorted, delta;
645 Scalar closestToLeftBoundDist, closestToRghtBoundDist;
650 notFlippedLeftBound = leftBound;
651 notFlippedRghtBound = rghtBound;
653 if ((Teuchos::ScalarTraits<SC>::real(rsumTarget) >= Teuchos::ScalarTraits<SC>::real(leftBound * as<Scalar>(nEntries))) &&
654 (Teuchos::ScalarTraits<SC>::real(rsumTarget) <= Teuchos::ScalarTraits<SC>::real(rghtBound * as<Scalar>(nEntries))))
655 hasFeasibleSol =
true;
657 hasFeasibleSol =
false;
658 return hasFeasibleSol;
663 aBigNumber = Teuchos::ScalarTraits<SC>::zero();
665 if (Teuchos::ScalarTraits<SC>::magnitude(orig[i]) > Teuchos::ScalarTraits<SC>::magnitude(aBigNumber))
666 aBigNumber = Teuchos::ScalarTraits<SC>::magnitude(orig[i]);
668 aBigNumber = aBigNumber + (Teuchos::ScalarTraits<SC>::magnitude(leftBound) + Teuchos::ScalarTraits<SC>::magnitude(rghtBound)) * as<Scalar>(100.0);
670 origSorted = &scalarData[0];
671 fixedSorted = &(scalarData[nEntries]);
674 for (
LocalOrdinal i = 0; i < nEntries; i++) inds[i] = i;
675 for (
LocalOrdinal i = 0; i < nEntries; i++) origSorted[i] = orig[i];
678 std::sort(inds, inds + nEntries,
679 [origSorted](
LocalOrdinal leftIndex,
LocalOrdinal rightIndex) {
return Teuchos::ScalarTraits<SC>::real(origSorted[leftIndex]) < Teuchos::ScalarTraits<SC>::real(origSorted[rightIndex]); });
681 for (
LocalOrdinal i = 0; i < nEntries; i++) origSorted[i] = orig[inds[i]];
683 closestToLeftBound = 0;
684 while ((closestToLeftBound < nEntries) && (Teuchos::ScalarTraits<SC>::real(origSorted[closestToLeftBound]) <= Teuchos::ScalarTraits<SC>::real(leftBound))) closestToLeftBound++;
687 closestToRghtBound = closestToLeftBound;
688 while ((closestToRghtBound < nEntries) && (Teuchos::ScalarTraits<SC>::real(origSorted[closestToRghtBound]) <= Teuchos::ScalarTraits<SC>::real(rghtBound))) closestToRghtBound++;
693 closestToLeftBoundDist = origSorted[closestToLeftBound] - leftBound;
694 if (closestToRghtBound == nEntries)
695 closestToRghtBoundDist = aBigNumber;
697 closestToRghtBoundDist = origSorted[closestToRghtBound] - rghtBound;
702 rowSumDeviation = leftBound * as<Scalar>(closestToLeftBound) + as<Scalar>((nEntries - closestToRghtBound)) * rghtBound - rsumTarget;
703 for (
LocalOrdinal i = closestToLeftBound; i < closestToRghtBound; i++) rowSumDeviation += origSorted[i];
708 if (Teuchos::ScalarTraits<SC>::real(rowSumDeviation) < Teuchos::ScalarTraits<SC>::real(Teuchos::ScalarTraits<SC>::zero())) {
711 leftBound = -rghtBound;
716 if ((nEntries % 2) == 1) origSorted[(nEntries / 2)] = -origSorted[(nEntries / 2)];
718 temp = origSorted[i];
719 origSorted[i] = -origSorted[nEntries - 1 - i];
720 origSorted[nEntries - i - 1] = -temp;
726 closestToLeftBound = nEntries - closestToRghtBound;
727 closestToRghtBound = nEntries - itemp;
728 closestToLeftBoundDist = origSorted[closestToLeftBound] - leftBound;
729 if (closestToRghtBound == nEntries)
730 closestToRghtBoundDist = aBigNumber;
732 closestToRghtBoundDist = origSorted[closestToRghtBound] - rghtBound;
734 rowSumDeviation = -rowSumDeviation;
739 for (
LocalOrdinal i = 0; i < closestToLeftBound; i++) fixedSorted[i] = leftBound;
740 for (
LocalOrdinal i = closestToLeftBound; i < closestToRghtBound; i++) fixedSorted[i] = origSorted[i];
741 for (
LocalOrdinal i = closestToRghtBound; i < nEntries; i++) fixedSorted[i] = rghtBound;
743 while ((Teuchos::ScalarTraits<SC>::magnitude(rowSumDeviation) > Teuchos::ScalarTraits<SC>::magnitude(as<Scalar>(1.e-10) * rsumTarget))) {
744 if (closestToRghtBound != closestToLeftBound)
745 delta = rowSumDeviation / as<Scalar>(closestToRghtBound - closestToLeftBound);
749 if (Teuchos::ScalarTraits<SC>::magnitude(closestToLeftBoundDist) <= Teuchos::ScalarTraits<SC>::magnitude(closestToRghtBoundDist)) {
750 if (Teuchos::ScalarTraits<SC>::magnitude(delta) <= Teuchos::ScalarTraits<SC>::magnitude(closestToLeftBoundDist)) {
751 rowSumDeviation = Teuchos::ScalarTraits<SC>::zero();
752 for (
LocalOrdinal i = closestToLeftBound; i < closestToRghtBound; i++) fixedSorted[i] = origSorted[i] - delta;
754 rowSumDeviation = rowSumDeviation - closestToLeftBoundDist;
755 fixedSorted[closestToLeftBound] = leftBound;
756 closestToLeftBound++;
757 if (closestToLeftBound < nEntries)
758 closestToLeftBoundDist = origSorted[closestToLeftBound] - leftBound;
760 closestToLeftBoundDist = aBigNumber;
763 if (Teuchos::ScalarTraits<SC>::magnitude(delta) <= Teuchos::ScalarTraits<SC>::magnitude(closestToRghtBoundDist)) {
765 for (
LocalOrdinal i = closestToLeftBound; i < closestToRghtBound; i++) fixedSorted[i] = origSorted[i] - delta;
767 rowSumDeviation = rowSumDeviation + closestToRghtBoundDist;
769 fixedSorted[closestToRghtBound] = origSorted[closestToRghtBound];
770 closestToRghtBound++;
772 if (closestToRghtBound >= nEntries)
773 closestToRghtBoundDist = aBigNumber;
775 closestToRghtBoundDist = origSorted[closestToRghtBound] - rghtBound;
783 if ((nEntries % 2) == 1) fixedSorted[(nEntries / 2)] = -fixedSorted[(nEntries / 2)];
785 temp = fixedSorted[i];
786 fixedSorted[i] = -fixedSorted[nEntries - 1 - i];
787 fixedSorted[nEntries - i - 1] = -temp;
790 for (
LocalOrdinal i = 0; i < nEntries; i++) fixedUnsorted[inds[i]] = fixedSorted[i];
794 bool lowerViolation =
false;
795 bool upperViolation =
false;
796 bool sumViolation =
false;
797 using TST = Teuchos::ScalarTraits<SC>;
800 if (TST::real(fixedUnsorted[i]) < TST::real(notFlippedLeftBound)) lowerViolation =
true;
801 if (TST::real(fixedUnsorted[i]) > TST::real(notFlippedRghtBound)) upperViolation =
true;
802 temp += fixedUnsorted[i];
804 SC tol = as<Scalar>(std::max(1.0e-8, as<double>(100 * TST::eps())));
805 if (TST::magnitude(temp - rsumTarget) > TST::magnitude(tol * rsumTarget)) sumViolation =
true;
807 TEUCHOS_TEST_FOR_EXCEPTION(lowerViolation,
Exceptions::RuntimeError,
"MueLu::SaPFactory::constrainRow: feasible solution but computation resulted in a lower bound violation??? ");
808 TEUCHOS_TEST_FOR_EXCEPTION(upperViolation,
Exceptions::RuntimeError,
"MueLu::SaPFactory::constrainRow: feasible solution but computation resulted in an upper bound violation??? ");
809 TEUCHOS_TEST_FOR_EXCEPTION(sumViolation,
Exceptions::RuntimeError,
"MueLu::SaPFactory::constrainRow: feasible solution but computation resulted in a row sum violation??? ");
811 return hasFeasibleSol;
1130 const RCP<Matrix>& Kn,
1131 const RCP<Matrix>& D0,
1132 const RCP<Matrix>& Pe_tent,
1133 const Scalar beta)
const {
1135 using XMM = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
1136 auto one = Teuchos::ScalarTraits<Scalar>::one();
1140 auto D0_diagKnInv = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(D0, Teuchos::Copy);
1141 D0_diagKnInv->rightScale(*diagKnInv);
1143 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> dummy;
1144 auto D0_diagKnInv_D0T = XMM::Multiply(*D0_diagKnInv,
false, *D0,
true, dummy,
GetOStream(
Runtime0));
1145 D0_diagKnInv = Teuchos::null;
1147 auto SM_Pe_tent = XMM::Multiply(*SM,
false, *Pe_tent,
false, dummy,
GetOStream(
Runtime0));
1148 auto D0_diagKnInv_D0T_SM_Pe_tent = XMM::Multiply(*D0_diagKnInv_D0T,
false, *SM_Pe_tent,
false, dummy,
GetOStream(
Runtime0));
1150 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> Pe;
1151 XMM::TwoMatrixAdd(*Pe_tent,
false, one, *D0_diagKnInv_D0T_SM_Pe_tent,
false, -beta, Pe,
GetOStream(
Runtime0));
1152 Pe->fillComplete(Pe_tent->getDomainMap(), Pe_tent->getRangeMap());
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Jacobi(typename Teuchos::ScalarTraits< Scalar >::magnitudeType omega, const Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Dinv, const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > C_in, Teuchos::FancyOStream &fos, const std::string &label, RCP< ParameterList > ¶ms)