100 const std::string prefix =
"MueLu::SaPFactory(" + levelIDs +
"): ";
102 typedef typename Teuchos::ScalarTraits<SC>::coordinateType Coordinate;
103 typedef typename Teuchos::ScalarTraits<SC>::magnitudeType MT;
108 RCP<const FactoryBase> initialPFact = GetFactory(
"P");
109 if (initialPFact == Teuchos::null) {
112 const ParameterList& pL = GetParameterList();
115 RCP<Matrix> A = Get<RCP<Matrix>>(fineLevel,
"A");
116 RCP<Matrix> Ptent = coarseLevel.
Get<RCP<Matrix>>(
"P", initialPFact.get());
120 if (Ptent == Teuchos::null) {
121 finalP = Teuchos::null;
122 Set(coarseLevel,
"P", finalP);
126 if (restrictionMode_) {
134 RCP<ParameterList> APparams;
135 if (pL.isSublist(
"matrixmatrix: kernel params"))
136 APparams = rcp(
new ParameterList(pL.sublist(
"matrixmatrix: kernel params")));
138 APparams = rcp(
new ParameterList);
139 if (coarseLevel.
IsAvailable(
"AP reuse data",
this)) {
140 GetOStream(
static_cast<MsgType>(
Runtime0 |
Test)) <<
"Reusing previous AP data" << std::endl;
142 APparams = coarseLevel.
Get<RCP<ParameterList>>(
"AP reuse data",
this);
144 if (APparams->isParameter(
"graph"))
145 finalP = APparams->get<RCP<Matrix>>(
"graph");
148 APparams->set(
"compute global constants: temporaries", APparams->get(
"compute global constants: temporaries",
false));
149 APparams->set(
"compute global constants", APparams->get(
"compute global constants",
false));
151 const SC
dampingFactor = as<SC>(pL.get<
double>(
"sa: damping factor"));
152 const LO maxEigenIterations = as<LO>(pL.get<
int>(
"sa: eigenvalue estimate num iterations"));
153 const bool estimateMaxEigen = pL.get<
bool>(
"sa: calculate eigenvalue estimate");
154 const bool useAbsValueRowSum = pL.get<
bool>(
"sa: use rowsumabs diagonal scaling");
155 const bool doQRStep = pL.get<
bool>(
"tentative: calculate qr");
156 const bool enforceConstraints = pL.get<
bool>(
"sa: enforce constraints");
157 const MT userDefinedMaxEigen = as<MT>(pL.get<
double>(
"sa: max eigenvalue"));
158 double dTol = pL.get<
double>(
"sa: diagonal replacement tolerance");
159 double dTol_rs = pL.get<
double>(
"sa: rowsumabs diagonal replacement tolerance");
160 const MT diagonalReplacementTolerance = (dTol == as<double>(-1) ? Teuchos::ScalarTraits<MT>::eps() * 100 : as<MT>(pL.get<
double>(
"sa: diagonal replacement tolerance")));
161 const MT diagonalReplacementTolerance_rs = (dTol_rs == as<double>(-1) ? Teuchos::ScalarTraits<MT>::eps() * 100 : as<MT>(pL.get<
double>(
"sa: rowsumabs diagonal replacement tolerance")));
163 const SC diagonalReplacementValue = as<SC>(pL.get<
double>(
"sa: rowsumabs diagonal replacement value"));
164 const bool replaceSingleEntryRowWithZero = pL.get<
bool>(
"sa: rowsumabs replace single entry row with zero");
165 const bool useAutomaticDiagTol = pL.get<
bool>(
"sa: rowsumabs use automatic diagonal tolerance");
169 "MueLu::TentativePFactory::MakeTentative: cannot use 'enforce constraints' and 'calculate qr' at the same time");
172 const bool specialMaxwell1Smoothing = pL.get<
bool>(
"sa: maxwell1 smoothing");
174 if (!specialMaxwell1Smoothing) {
177 Teuchos::RCP<Vector> invDiag;
178 if (userDefinedMaxEigen == -1.) {
180 lambdaMax = A->GetMaxEigenvalueEstimate();
181 if (lambdaMax == -Teuchos::ScalarTraits<SC>::one() || estimateMaxEigen) {
182 GetOStream(
Statistics1) <<
"Calculating max eigenvalue estimate now (max iters = " << maxEigenIterations << ((useAbsValueRowSum) ?
", use rowSumAbs diagonal)" :
", use point diagonal)") << std::endl;
183 Coordinate stopTol = 1e-4;
184 if (useAbsValueRowSum) {
185 const bool returnReciprocal =
true;
187 diagonalReplacementTolerance_rs,
188 diagonalReplacementValue,
189 replaceSingleEntryRowWithZero,
190 useAutomaticDiagTol);
192 "SaPFactory: eigenvalue estimate: diagonal reciprocal is null.");
196 A->SetMaxEigenvalueEstimate(lambdaMax);
198 GetOStream(
Statistics1) <<
"Using cached max eigenvalue estimate" << std::endl;
201 lambdaMax = userDefinedMaxEigen;
202 A->SetMaxEigenvalueEstimate(lambdaMax);
204 MT omega = Teuchos::ScalarTraits<SC>::magnitude(
dampingFactor) / Teuchos::ScalarTraits<SC>::magnitude(lambdaMax);
205 GetOStream(
Statistics1) <<
"Prolongator damping factor = " << omega <<
" (|" <<
dampingFactor <<
" / " << lambdaMax <<
"|)" << std::endl;
209 if (!useAbsValueRowSum)
211 else if (invDiag == Teuchos::null) {
212 GetOStream(
Runtime0) <<
"Using rowsumabs diagonal" << std::endl;
213 const bool returnReciprocal =
true;
215 diagonalReplacementTolerance_rs,
216 diagonalReplacementValue,
217 replaceSingleEntryRowWithZero,
218 useAutomaticDiagTol);
219 TEUCHOS_TEST_FOR_EXCEPTION(invDiag.is_null(),
Exceptions::RuntimeError,
"SaPFactory: diagonal reciprocal is null.");
222 TEUCHOS_TEST_FOR_EXCEPTION(!std::isfinite(omega),
Exceptions::RuntimeError,
"Prolongator damping factor needs to be finite.");
227 finalP =
MueLu::IteratorOps<SC, LO, GO, NO>::Jacobi(omega, *invDiag, *A, *Ptent, finalP, GetOStream(
Statistics2), std::string(
"MueLu::SaP-") +
toString(coarseLevel.
GetLevelID()), APparams);
228 if (enforceConstraints) {
229 if (!pL.get<
bool>(
"use kokkos refactor")) {
230 if (A->GetFixedBlockSize() == 1)
231 optimalSatisfyPConstraintsForScalarPDEsNonKokkos(finalP);
233 SatisfyPConstraintsNonKokkos(A, finalP);
238 SatisfyPConstraints(A, finalP);
254 const SC nodalDampingFactor = as<SC>(pL.get<
double>(
"sa: nodal damping factor"));
256 const bool nodalAndEdgeSmoothing = ((fineLevel.
IsAvailable(
"D0") && fineLevel.
IsAvailable(
"NodeMatrix")) && (nodalDampingFactor != Teuchos::ScalarTraits<SC>::zero()) && (fineLevel.
Get<RCP<Matrix>>(
"NodeMatrix")->GetMaxEigenvalueEstimate() != -Teuchos::ScalarTraits<SC>::one()));
257 const bool edgeSmoothing = (fineLevel.
IsAvailable(
"CurlCurl") && (
dampingFactor != Teuchos::ScalarTraits<SC>::zero()));
259 RCP<Matrix> P_afterNodalAndEdgeSmoothing;
260 if (nodalAndEdgeSmoothing) {
261 auto D0 = fineLevel.
Get<RCP<Matrix>>(
"D0");
262 auto NodeMatrix = fineLevel.
Get<RCP<Matrix>>(
"NodeMatrix");
264 auto lambdaMaxNodal = NodeMatrix->GetMaxEigenvalueEstimate();
265 MT beta = Teuchos::ScalarTraits<SC>::magnitude(nodalDampingFactor) / Teuchos::ScalarTraits<SC>::magnitude(lambdaMaxNodal);
266 GetOStream(
Statistics1) <<
"Maxwell1 prolongator nodal damping factor = " << beta <<
" (|" << nodalDampingFactor <<
" / " << lambdaMaxNodal <<
"|)" << std::endl;
267 TEUCHOS_TEST_FOR_EXCEPTION(lambdaMaxNodal == -Teuchos::ScalarTraits<SC>::one(),
Exceptions::RuntimeError,
"Prolongator damping factor obtained from NodeMatrix is -1.")
269 TEUCHOS_TEST_FOR_EXCEPTION(!std::isfinite(beta),
Exceptions::RuntimeError,
"Prolongator damping factor needs to be finite.");
273 P_afterNodalAndEdgeSmoothing = JacobiMaxwell1(A, NodeMatrix, D0, Ptent, beta);
277 GetOStream(
Warnings) <<
"Skipping nodal&edge smoothing step since D0 or NodeMatrix matrix is not available\n";
278 else if (nodalDampingFactor == Teuchos::ScalarTraits<SC>::zero())
279 GetOStream(
Statistics1) <<
"Skipping nodal&edge smoothing step since nodal damping factor is zero\n";
280 else if (fineLevel.
Get<RCP<Matrix>>(
"NodeMatrix")->GetMaxEigenvalueEstimate() == -Teuchos::ScalarTraits<SC>::one())
281 GetOStream(
Warnings) <<
"Skipping nodal&edge smoothing step since NodeMatrix matrix has invalid eigenvalue estimate\n";
282 P_afterNodalAndEdgeSmoothing = Ptent;
286 auto CurlCurl = fineLevel.
Get<RCP<Matrix>>(
"CurlCurl", GetFactory(
"CurlCurl").get());
289 Teuchos::RCP<Vector> invDiag;
290 if (userDefinedMaxEigen == -1.) {
292 lambdaMax = CurlCurl->GetMaxEigenvalueEstimate();
293 if (lambdaMax == -Teuchos::ScalarTraits<SC>::one() || estimateMaxEigen) {
294 GetOStream(
Statistics1) <<
"Calculating max eigenvalue estimate now (max iters = " << maxEigenIterations << ((useAbsValueRowSum) ?
", use rowSumAbs diagonal)" :
", use point diagonal)") << std::endl;
295 Coordinate stopTol = 1e-4;
296 if (useAbsValueRowSum) {
297 const bool returnReciprocal =
true;
299 diagonalReplacementTolerance_rs,
300 diagonalReplacementValue,
301 replaceSingleEntryRowWithZero,
302 useAutomaticDiagTol);
304 "SaPFactory: eigenvalue estimate: diagonal reciprocal is null.");
307 lambdaMax =
Utilities::PowerMethod(*CurlCurl,
true, maxEigenIterations, stopTol, diagonalReplacementTolerance);
308 CurlCurl->SetMaxEigenvalueEstimate(lambdaMax);
310 GetOStream(
Statistics1) <<
"Using cached max eigenvalue estimate" << std::endl;
313 lambdaMax = userDefinedMaxEigen;
314 CurlCurl->SetMaxEigenvalueEstimate(lambdaMax);
317 if (!useAbsValueRowSum)
319 else if (invDiag == Teuchos::null) {
320 GetOStream(
Runtime0) <<
"Using rowsumabs diagonal" << std::endl;
321 const bool returnReciprocal =
true;
323 diagonalReplacementTolerance_rs,
324 diagonalReplacementValue,
325 replaceSingleEntryRowWithZero,
326 useAutomaticDiagTol);
327 TEUCHOS_TEST_FOR_EXCEPTION(invDiag.is_null(),
Exceptions::RuntimeError,
"SaPFactory: diagonal reciprocal is null.");
330 MT alpha = Teuchos::ScalarTraits<SC>::magnitude(
dampingFactor) / Teuchos::ScalarTraits<SC>::magnitude(lambdaMax);
331 TEUCHOS_TEST_FOR_EXCEPTION(!std::isfinite(alpha),
Exceptions::RuntimeError,
"Prolongator damping factor needs to be finite.");
333 GetOStream(
Statistics1) <<
"Maxwell1 prolongator edge damping factor = " << alpha <<
" (|" <<
dampingFactor <<
" / " << lambdaMax <<
"|)" << std::endl;
338 finalP =
MueLu::IteratorOps<SC, LO, GO, NO>::Jacobi(alpha, *invDiag, *CurlCurl, *P_afterNodalAndEdgeSmoothing, finalP, GetOStream(
Statistics2), std::string(
"MueLu::SaP-") +
toString(coarseLevel.
GetLevelID()), APparams);
342 GetOStream(
Warnings) <<
"Skipping edge-only smoothing step since CurlCurl matrix is not available\n";
344 GetOStream(
Statistics1) <<
"Maxwell1 prolongator edge smoothing skipped" << std::endl;
345 finalP = P_afterNodalAndEdgeSmoothing;
351 if (!restrictionMode_) {
353 if (!finalP.is_null()) {
354 std::ostringstream oss;
356 finalP->setObjectLabel(oss.str());
358 Set(coarseLevel,
"P", finalP);
360 APparams->set(
"graph", finalP);
361 Set(coarseLevel,
"AP reuse data", APparams);
364 if (Ptent->IsView(
"stridedMaps"))
365 finalP->CreateView(
"stridedMaps", Ptent);
373 std::ostringstream oss;
375 R->setObjectLabel(oss.str());
379 Set(coarseLevel,
"R", R);
382 if (Ptent->IsView(
"stridedMaps"))
383 R->CreateView(
"stridedMaps", Ptent,
true );
387 RCP<ParameterList> params = rcp(
new ParameterList());
388 params->set(
"printLoadBalancingInfo",
true);
389 params->set(
"printCommInfo",
true);
413 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
414 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
415 LO nPDEs = A->GetFixedBlockSize();
416 Teuchos::ArrayRCP<Scalar> ConstraintViolationSum(nPDEs);
417 Teuchos::ArrayRCP<Scalar> Rsum(nPDEs);
418 Teuchos::ArrayRCP<size_t> nPositive(nPDEs);
419 for (
size_t k = 0; k < (size_t)nPDEs; k++) ConstraintViolationSum[k] = zero;
420 for (
size_t k = 0; k < (size_t)nPDEs; k++) Rsum[k] = zero;
421 for (
size_t k = 0; k < (size_t)nPDEs; k++) nPositive[k] = 0;
423 for (
size_t i = 0; i < as<size_t>(P->getRowMap()->getLocalNumElements()); i++) {
424 Teuchos::ArrayView<const LocalOrdinal> indices;
425 Teuchos::ArrayView<const Scalar> vals1;
426 Teuchos::ArrayView<Scalar> vals;
427 P->getLocalRowView((LO)i, indices, vals1);
428 size_t nnz = indices.size();
429 if (nnz == 0)
continue;
431 vals = ArrayView<Scalar>(
const_cast<SC*
>(vals1.getRawPtr()), nnz);
433 bool checkRow =
true;
438 for (LO j = 0; j < indices.size(); j++) {
439 Rsum[j % nPDEs] += vals[j];
440 if (Teuchos::ScalarTraits<SC>::real(vals[j]) < Teuchos::ScalarTraits<SC>::real(zero)) {
441 ConstraintViolationSum[j % nPDEs] += vals[j];
444 if (Teuchos::ScalarTraits<SC>::real(vals[j]) != Teuchos::ScalarTraits<SC>::real(zero))
445 (nPositive[j % nPDEs])++;
447 if (Teuchos::ScalarTraits<SC>::real(vals[j]) > Teuchos::ScalarTraits<SC>::real(1.00001)) {
448 ConstraintViolationSum[j % nPDEs] += (vals[j] - one);
458 for (
size_t k = 0; k < (size_t)nPDEs; k++) {
459 if (Teuchos::ScalarTraits<SC>::real(Rsum[k]) < Teuchos::ScalarTraits<SC>::magnitude(zero)) {
460 ConstraintViolationSum[k] += (-Rsum[k]);
461 }
else if (Teuchos::ScalarTraits<SC>::real(Rsum[k]) > Teuchos::ScalarTraits<SC>::magnitude(1.00001)) {
462 ConstraintViolationSum[k] += (one - Rsum[k]);
467 for (
size_t k = 0; k < (size_t)nPDEs; k++) {
468 if (Teuchos::ScalarTraits<SC>::magnitude(ConstraintViolationSum[k]) != Teuchos::ScalarTraits<SC>::magnitude(zero))
473 for (LO j = 0; j < indices.size(); j++) {
474 if (Teuchos::ScalarTraits<SC>::real(vals[j]) > Teuchos::ScalarTraits<SC>::real(zero)) {
475 vals[j] += (ConstraintViolationSum[j % nPDEs] / (as<Scalar>(nPositive[j % nPDEs])));
478 for (
size_t k = 0; k < (size_t)nPDEs; k++) ConstraintViolationSum[k] = zero;
480 for (
size_t k = 0; k < (size_t)nPDEs; k++) Rsum[k] = zero;
481 for (
size_t k = 0; k < (size_t)nPDEs; k++) nPositive[k] = 0;
639 Scalar notFlippedLeftBound, notFlippedRghtBound, aBigNumber, *origSorted;
640 Scalar rowSumDeviation, temp, *fixedSorted, delta;
641 Scalar closestToLeftBoundDist, closestToRghtBoundDist;
646 notFlippedLeftBound = leftBound;
647 notFlippedRghtBound = rghtBound;
649 if ((Teuchos::ScalarTraits<SC>::real(rsumTarget) >= Teuchos::ScalarTraits<SC>::real(leftBound * as<Scalar>(nEntries))) &&
650 (Teuchos::ScalarTraits<SC>::real(rsumTarget) <= Teuchos::ScalarTraits<SC>::real(rghtBound * as<Scalar>(nEntries))))
651 hasFeasibleSol =
true;
653 hasFeasibleSol =
false;
654 return hasFeasibleSol;
659 aBigNumber = Teuchos::ScalarTraits<SC>::zero();
661 if (Teuchos::ScalarTraits<SC>::magnitude(orig[i]) > Teuchos::ScalarTraits<SC>::magnitude(aBigNumber))
662 aBigNumber = Teuchos::ScalarTraits<SC>::magnitude(orig[i]);
664 aBigNumber = aBigNumber + (Teuchos::ScalarTraits<SC>::magnitude(leftBound) + Teuchos::ScalarTraits<SC>::magnitude(rghtBound)) * as<Scalar>(100.0);
666 origSorted = &scalarData[0];
667 fixedSorted = &(scalarData[nEntries]);
670 for (
LocalOrdinal i = 0; i < nEntries; i++) inds[i] = i;
671 for (
LocalOrdinal i = 0; i < nEntries; i++) origSorted[i] = orig[i];
674 std::sort(inds, inds + nEntries,
675 [origSorted](
LocalOrdinal leftIndex,
LocalOrdinal rightIndex) {
return Teuchos::ScalarTraits<SC>::real(origSorted[leftIndex]) < Teuchos::ScalarTraits<SC>::real(origSorted[rightIndex]); });
677 for (
LocalOrdinal i = 0; i < nEntries; i++) origSorted[i] = orig[inds[i]];
679 closestToLeftBound = 0;
680 while ((closestToLeftBound < nEntries) && (Teuchos::ScalarTraits<SC>::real(origSorted[closestToLeftBound]) <= Teuchos::ScalarTraits<SC>::real(leftBound))) closestToLeftBound++;
683 closestToRghtBound = closestToLeftBound;
684 while ((closestToRghtBound < nEntries) && (Teuchos::ScalarTraits<SC>::real(origSorted[closestToRghtBound]) <= Teuchos::ScalarTraits<SC>::real(rghtBound))) closestToRghtBound++;
689 closestToLeftBoundDist = origSorted[closestToLeftBound] - leftBound;
690 if (closestToRghtBound == nEntries)
691 closestToRghtBoundDist = aBigNumber;
693 closestToRghtBoundDist = origSorted[closestToRghtBound] - rghtBound;
698 rowSumDeviation = leftBound * as<Scalar>(closestToLeftBound) + as<Scalar>((nEntries - closestToRghtBound)) * rghtBound - rsumTarget;
699 for (
LocalOrdinal i = closestToLeftBound; i < closestToRghtBound; i++) rowSumDeviation += origSorted[i];
704 if (Teuchos::ScalarTraits<SC>::real(rowSumDeviation) < Teuchos::ScalarTraits<SC>::real(Teuchos::ScalarTraits<SC>::zero())) {
707 leftBound = -rghtBound;
712 if ((nEntries % 2) == 1) origSorted[(nEntries / 2)] = -origSorted[(nEntries / 2)];
714 temp = origSorted[i];
715 origSorted[i] = -origSorted[nEntries - 1 - i];
716 origSorted[nEntries - i - 1] = -temp;
722 closestToLeftBound = nEntries - closestToRghtBound;
723 closestToRghtBound = nEntries - itemp;
724 closestToLeftBoundDist = origSorted[closestToLeftBound] - leftBound;
725 if (closestToRghtBound == nEntries)
726 closestToRghtBoundDist = aBigNumber;
728 closestToRghtBoundDist = origSorted[closestToRghtBound] - rghtBound;
730 rowSumDeviation = -rowSumDeviation;
735 for (
LocalOrdinal i = 0; i < closestToLeftBound; i++) fixedSorted[i] = leftBound;
736 for (
LocalOrdinal i = closestToLeftBound; i < closestToRghtBound; i++) fixedSorted[i] = origSorted[i];
737 for (
LocalOrdinal i = closestToRghtBound; i < nEntries; i++) fixedSorted[i] = rghtBound;
739 while ((Teuchos::ScalarTraits<SC>::magnitude(rowSumDeviation) > Teuchos::ScalarTraits<SC>::magnitude(as<Scalar>(1.e-10) * rsumTarget))) {
740 if (closestToRghtBound != closestToLeftBound)
741 delta = rowSumDeviation / as<Scalar>(closestToRghtBound - closestToLeftBound);
745 if (Teuchos::ScalarTraits<SC>::magnitude(closestToLeftBoundDist) <= Teuchos::ScalarTraits<SC>::magnitude(closestToRghtBoundDist)) {
746 if (Teuchos::ScalarTraits<SC>::magnitude(delta) <= Teuchos::ScalarTraits<SC>::magnitude(closestToLeftBoundDist)) {
747 rowSumDeviation = Teuchos::ScalarTraits<SC>::zero();
748 for (
LocalOrdinal i = closestToLeftBound; i < closestToRghtBound; i++) fixedSorted[i] = origSorted[i] - delta;
750 rowSumDeviation = rowSumDeviation - closestToLeftBoundDist;
751 fixedSorted[closestToLeftBound] = leftBound;
752 closestToLeftBound++;
753 if (closestToLeftBound < nEntries)
754 closestToLeftBoundDist = origSorted[closestToLeftBound] - leftBound;
756 closestToLeftBoundDist = aBigNumber;
759 if (Teuchos::ScalarTraits<SC>::magnitude(delta) <= Teuchos::ScalarTraits<SC>::magnitude(closestToRghtBoundDist)) {
761 for (
LocalOrdinal i = closestToLeftBound; i < closestToRghtBound; i++) fixedSorted[i] = origSorted[i] - delta;
763 rowSumDeviation = rowSumDeviation + closestToRghtBoundDist;
765 fixedSorted[closestToRghtBound] = origSorted[closestToRghtBound];
766 closestToRghtBound++;
768 if (closestToRghtBound >= nEntries)
769 closestToRghtBoundDist = aBigNumber;
771 closestToRghtBoundDist = origSorted[closestToRghtBound] - rghtBound;
779 if ((nEntries % 2) == 1) fixedSorted[(nEntries / 2)] = -fixedSorted[(nEntries / 2)];
781 temp = fixedSorted[i];
782 fixedSorted[i] = -fixedSorted[nEntries - 1 - i];
783 fixedSorted[nEntries - i - 1] = -temp;
786 for (
LocalOrdinal i = 0; i < nEntries; i++) fixedUnsorted[inds[i]] = fixedSorted[i];
790 bool lowerViolation =
false;
791 bool upperViolation =
false;
792 bool sumViolation =
false;
793 using TST = Teuchos::ScalarTraits<SC>;
796 if (TST::real(fixedUnsorted[i]) < TST::real(notFlippedLeftBound)) lowerViolation =
true;
797 if (TST::real(fixedUnsorted[i]) > TST::real(notFlippedRghtBound)) upperViolation =
true;
798 temp += fixedUnsorted[i];
800 SC tol = as<Scalar>(std::max(1.0e-8, as<double>(100 * TST::eps())));
801 if (TST::magnitude(temp - rsumTarget) > TST::magnitude(tol * rsumTarget)) sumViolation =
true;
803 TEUCHOS_TEST_FOR_EXCEPTION(lowerViolation,
Exceptions::RuntimeError,
"MueLu::SaPFactory::constrainRow: feasible solution but computation resulted in a lower bound violation??? ");
804 TEUCHOS_TEST_FOR_EXCEPTION(upperViolation,
Exceptions::RuntimeError,
"MueLu::SaPFactory::constrainRow: feasible solution but computation resulted in an upper bound violation??? ");
805 TEUCHOS_TEST_FOR_EXCEPTION(sumViolation,
Exceptions::RuntimeError,
"MueLu::SaPFactory::constrainRow: feasible solution but computation resulted in a row sum violation??? ");
807 return hasFeasibleSol;
1126 const RCP<Matrix>& Kn,
1127 const RCP<Matrix>& D0,
1128 const RCP<Matrix>& Pe_tent,
1129 const Scalar beta)
const {
1131 using XMM = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
1132 auto one = Teuchos::ScalarTraits<Scalar>::one();
1136 auto D0_diagKnInv = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(D0, Teuchos::Copy);
1137 D0_diagKnInv->rightScale(*diagKnInv);
1139 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> dummy;
1140 auto D0_diagKnInv_D0T = XMM::Multiply(*D0_diagKnInv,
false, *D0,
true, dummy, GetOStream(
Runtime0));
1141 D0_diagKnInv = Teuchos::null;
1143 auto SM_Pe_tent = XMM::Multiply(*SM,
false, *Pe_tent,
false, dummy, GetOStream(
Runtime0));
1144 auto D0_diagKnInv_D0T_SM_Pe_tent = XMM::Multiply(*D0_diagKnInv_D0T,
false, *SM_Pe_tent,
false, dummy, GetOStream(
Runtime0));
1146 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> Pe;
1147 XMM::TwoMatrixAdd(*Pe_tent,
false, one, *D0_diagKnInv_D0T_SM_Pe_tent,
false, -beta, Pe, GetOStream(
Runtime0));
1148 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)