46 #ifndef THYRA_MUELU_PRECONDITIONER_FACTORY_DEF_HPP
47 #define THYRA_MUELU_PRECONDITIONER_FACTORY_DEF_HPP
52 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
55 #if ((defined(HAVE_TPETRA_INST_DOUBLE) && defined(HAVE_TPETRA_INST_FLOAT) && !defined(HAVE_TPETRA_INST_COMPLEX_DOUBLE) && !defined(HAVE_TPETRA_INST_COMPLEX_FLOAT)) || \
56 (!defined(HAVE_TPETRA_INST_DOUBLE) && !defined(HAVE_TPETRA_INST_FLOAT) && defined(HAVE_TPETRA_INST_COMPLEX_DOUBLE) && defined(HAVE_TPETRA_INST_COMPLEX_FLOAT)) || \
57 (defined(HAVE_TPETRA_INST_DOUBLE) && defined(HAVE_TPETRA_INST_FLOAT) && defined(HAVE_TPETRA_INST_COMPLEX_DOUBLE) && defined(HAVE_TPETRA_INST_COMPLEX_FLOAT)))
58 #define MUELU_CAN_USE_MIXED_PRECISION
66 using Teuchos::rcp_const_cast;
67 using Teuchos::rcp_dynamic_cast;
69 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
70 bool Converters<Scalar, LocalOrdinal, GlobalOrdinal, Node>::replaceWithXpetra(ParameterList& paramList, std::string parameterName) {
73 typedef Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpThyUtils;
81 typedef Thyra::LinearOpBase<Scalar> ThyLinOpBase;
82 typedef Thyra::DiagonalLinearOpBase<Scalar> ThyDiagLinOpBase;
89 typedef Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> thyTpV;
92 #if defined(MUELU_CAN_USE_MIXED_PRECISION)
97 if (paramList.isParameter(parameterName)) {
98 if (paramList.isType<RCP<XpMat> >(parameterName))
100 else if (paramList.isType<RCP<const XpMat> >(parameterName)) {
101 RCP<const XpMat> constM = paramList.get<RCP<const XpMat> >(parameterName);
102 paramList.remove(parameterName);
103 RCP<XpMat> M = rcp_const_cast<XpMat>(constM);
104 paramList.set<RCP<XpMat> >(parameterName, M);
106 }
else if (paramList.isType<RCP<XpMultVec> >(parameterName))
108 else if (paramList.isType<RCP<const XpMultVec> >(parameterName)) {
109 RCP<const XpMultVec> constX = paramList.get<RCP<const XpMultVec> >(parameterName);
110 paramList.remove(parameterName);
111 RCP<XpMultVec> X = rcp_const_cast<XpMultVec>(constX);
112 paramList.set<RCP<XpMultVec> >(parameterName, X);
114 }
else if (paramList.isType<RCP<XpMagMultVec> >(parameterName))
116 else if (paramList.isType<RCP<const XpMagMultVec> >(parameterName)) {
117 RCP<const XpMagMultVec> constX = paramList.get<RCP<const XpMagMultVec> >(parameterName);
118 paramList.remove(parameterName);
119 RCP<XpMagMultVec> X = rcp_const_cast<XpMagMultVec>(constX);
120 paramList.set<RCP<XpMagMultVec> >(parameterName, X);
122 }
else if (paramList.isType<RCP<TpCrsMat> >(parameterName)) {
123 RCP<TpCrsMat> tM = paramList.get<RCP<TpCrsMat> >(parameterName);
124 paramList.remove(parameterName);
125 RCP<XpMat> xM = MueLu::TpetraCrs_To_XpetraMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tM);
126 paramList.set<RCP<XpMat> >(parameterName, xM);
128 }
else if (paramList.isType<RCP<tMV> >(parameterName)) {
129 RCP<tMV> tpetra_X = paramList.get<RCP<tMV> >(parameterName);
130 paramList.remove(parameterName);
131 RCP<XpMultVec> X = MueLu::TpetraMultiVector_To_XpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpetra_X);
132 paramList.set<RCP<XpMultVec> >(parameterName, X);
135 }
else if (paramList.isType<RCP<tMagMV> >(parameterName)) {
136 RCP<tMagMV> tpetra_X = paramList.get<RCP<tMagMV> >(parameterName);
137 paramList.remove(parameterName);
138 RCP<XpMagMultVec> X = MueLu::TpetraMultiVector_To_XpetraMultiVector<Magnitude, LocalOrdinal, GlobalOrdinal, Node>(tpetra_X);
139 paramList.set<RCP<XpMagMultVec> >(parameterName, X);
143 #if defined(MUELU_CAN_USE_MIXED_PRECISION)
144 else if (paramList.isType<RCP<tHalfMagMV> >(parameterName)) {
145 RCP<tHalfMagMV> tpetra_hX = paramList.get<RCP<tHalfMagMV> >(parameterName);
146 paramList.remove(parameterName);
147 RCP<tMagMV> tpetra_X =
rcp(
new tMagMV(tpetra_hX->getMap(), tpetra_hX->getNumVectors()));
149 RCP<XpMagMultVec> X = MueLu::TpetraMultiVector_To_XpetraMultiVector<Magnitude, LocalOrdinal, GlobalOrdinal, Node>(tpetra_X);
150 paramList.set<RCP<XpMagMultVec> >(parameterName, X);
155 else if (paramList.isType<RCP<const ThyDiagLinOpBase> >(parameterName) ||
156 (paramList.isType<RCP<const ThyLinOpBase> >(parameterName) && !rcp_dynamic_cast<const ThyDiagLinOpBase>(paramList.get<RCP<const ThyLinOpBase> >(parameterName)).is_null())) {
157 RCP<const ThyDiagLinOpBase> thyM;
158 if (paramList.isType<RCP<const ThyDiagLinOpBase> >(parameterName))
159 thyM = paramList.get<RCP<const ThyDiagLinOpBase> >(parameterName);
161 thyM = rcp_dynamic_cast<
const ThyDiagLinOpBase>(paramList.get<RCP<const ThyLinOpBase> >(parameterName),
true);
162 paramList.remove(parameterName);
163 RCP<const Thyra::VectorBase<Scalar> > diag = thyM->getDiag();
165 RCP<const XpVec> xpDiag;
166 if (!rcp_dynamic_cast<const thyTpV>(diag).
is_null()) {
167 RCP<const tV> tDiag = Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getConstTpetraVector(diag);
168 if (!tDiag.is_null())
173 paramList.set<RCP<XpMat> >(parameterName, M);
175 }
else if (paramList.isType<RCP<const ThyLinOpBase> >(parameterName)) {
176 RCP<const ThyLinOpBase> thyM = paramList.get<RCP<const ThyLinOpBase> >(parameterName);
177 paramList.remove(parameterName);
179 RCP<XpMat> M = XpThyUtils::toXpetra(Teuchos::rcp_const_cast<ThyLinOpBase>(thyM));
180 paramList.set<RCP<XpMat> >(parameterName, M);
181 }
catch (std::exception& e) {
182 RCP<XpOp> M = XpThyUtils::toXpetraOperator(Teuchos::rcp_const_cast<ThyLinOpBase>(thyM));
186 if (tO->hasDiagonal()) {
187 diag =
rcp(
new tV(tO->getRangeMap()));
188 tO->getLocalDiagCopy(*diag);
192 auto op = rcp_dynamic_cast<XpOp>(tpFOp);
193 paramList.set<RCP<XpOp> >(parameterName, op);
204 #ifdef HAVE_MUELU_EPETRA
205 template <
class GlobalOrdinal>
206 bool Converters<double, int, GlobalOrdinal, Tpetra::KokkosCompat::KokkosSerialWrapperNode>::replaceWithXpetra(ParameterList& paramList, std::string parameterName) {
209 typedef Tpetra::KokkosCompat::KokkosSerialWrapperNode
Node;
212 typedef Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpThyUtils;
220 typedef Thyra::LinearOpBase<Scalar> ThyLinOpBase;
221 typedef Thyra::DiagonalLinearOpBase<Scalar> ThyDiagLinOpBase;
222 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThyVSBase;
227 typedef Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> thyTpV;
230 #if defined(MUELU_CAN_USE_MIXED_PRECISION)
234 #if defined(HAVE_MUELU_EPETRA)
238 if (paramList.isParameter(parameterName)) {
239 if (paramList.isType<RCP<XpMat> >(parameterName))
241 else if (paramList.isType<RCP<const XpMat> >(parameterName)) {
242 RCP<const XpMat> constM = paramList.get<RCP<const XpMat> >(parameterName);
243 paramList.remove(parameterName);
244 RCP<XpMat> M = rcp_const_cast<XpMat>(constM);
245 paramList.set<RCP<XpMat> >(parameterName, M);
247 }
else if (paramList.isType<RCP<XpMultVec> >(parameterName))
249 else if (paramList.isType<RCP<const XpMultVec> >(parameterName)) {
250 RCP<const XpMultVec> constX = paramList.get<RCP<const XpMultVec> >(parameterName);
251 paramList.remove(parameterName);
252 RCP<XpMultVec> X = rcp_const_cast<XpMultVec>(constX);
253 paramList.set<RCP<XpMultVec> >(parameterName, X);
255 }
else if (paramList.isType<RCP<XpMagMultVec> >(parameterName))
257 else if (paramList.isType<RCP<const XpMagMultVec> >(parameterName)) {
258 RCP<const XpMagMultVec> constX = paramList.get<RCP<const XpMagMultVec> >(parameterName);
259 paramList.remove(parameterName);
260 RCP<XpMagMultVec> X = rcp_const_cast<XpMagMultVec>(constX);
261 paramList.set<RCP<XpMagMultVec> >(parameterName, X);
263 }
else if (paramList.isType<RCP<TpCrsMat> >(parameterName)) {
264 RCP<TpCrsMat> tM = paramList.get<RCP<TpCrsMat> >(parameterName);
265 paramList.remove(parameterName);
266 RCP<XpMat> xM = MueLu::TpetraCrs_To_XpetraMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tM);
267 paramList.set<RCP<XpMat> >(parameterName, xM);
269 }
else if (paramList.isType<RCP<tMV> >(parameterName)) {
270 RCP<tMV> tpetra_X = paramList.get<RCP<tMV> >(parameterName);
271 paramList.remove(parameterName);
272 RCP<XpMultVec> X = MueLu::TpetraMultiVector_To_XpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpetra_X);
273 paramList.set<RCP<XpMultVec> >(parameterName, X);
276 }
else if (paramList.isType<RCP<tMagMV> >(parameterName)) {
277 RCP<tMagMV> tpetra_X = paramList.get<RCP<tMagMV> >(parameterName);
278 paramList.remove(parameterName);
279 RCP<XpMagMultVec> X = MueLu::TpetraMultiVector_To_XpetraMultiVector<Magnitude, LocalOrdinal, GlobalOrdinal, Node>(tpetra_X);
280 paramList.set<RCP<XpMagMultVec> >(parameterName, X);
284 #if defined(MUELU_CAN_USE_MIXED_PRECISION)
285 else if (paramList.isType<RCP<tHalfMagMV> >(parameterName)) {
286 RCP<tHalfMagMV> tpetra_hX = paramList.get<RCP<tHalfMagMV> >(parameterName);
287 paramList.remove(parameterName);
288 RCP<tMagMV> tpetra_X =
rcp(
new tMagMV(tpetra_hX->getMap(), tpetra_hX->getNumVectors()));
290 RCP<XpMagMultVec> X = MueLu::TpetraMultiVector_To_XpetraMultiVector<Magnitude, LocalOrdinal, GlobalOrdinal, Node>(tpetra_X);
291 paramList.set<RCP<XpMagMultVec> >(parameterName, X);
296 #ifdef HAVE_MUELU_EPETRA
297 else if (paramList.isType<RCP<Epetra_CrsMatrix> >(parameterName)) {
298 RCP<Epetra_CrsMatrix> eM = paramList.get<RCP<Epetra_CrsMatrix> >(parameterName);
299 paramList.remove(parameterName);
300 RCP<XpEpCrsMat> xeM =
rcp(
new XpEpCrsMat(eM));
301 RCP<XpCrsMat> xCrsM = rcp_dynamic_cast<XpCrsMat>(xeM,
true);
302 RCP<XpCrsMatWrap> xwM =
rcp(
new XpCrsMatWrap(xCrsM));
303 RCP<XpMat> xM = rcp_dynamic_cast<XpMat>(xwM);
304 paramList.set<RCP<XpMat> >(parameterName, xM);
306 }
else if (paramList.isType<RCP<Epetra_MultiVector> >(parameterName)) {
307 RCP<Epetra_MultiVector> epetra_X = Teuchos::null;
308 epetra_X = paramList.get<RCP<Epetra_MultiVector> >(parameterName);
309 paramList.remove(parameterName);
312 RCP<XpMultVec> X = rcp_dynamic_cast<XpMultVec>(xpEpXMult,
true);
313 paramList.set<RCP<XpMultVec> >(parameterName, X);
317 else if (paramList.isType<RCP<const ThyDiagLinOpBase> >(parameterName) ||
318 (paramList.isType<RCP<const ThyLinOpBase> >(parameterName) && !rcp_dynamic_cast<const ThyDiagLinOpBase>(paramList.get<RCP<const ThyLinOpBase> >(parameterName)).
is_null())) {
319 RCP<const ThyDiagLinOpBase> thyM;
320 if (paramList.isType<RCP<const ThyDiagLinOpBase> >(parameterName))
321 thyM = paramList.get<RCP<const ThyDiagLinOpBase> >(parameterName);
323 thyM = rcp_dynamic_cast<
const ThyDiagLinOpBase>(paramList.get<RCP<const ThyLinOpBase> >(parameterName),
true);
324 paramList.remove(parameterName);
325 RCP<const Thyra::VectorBase<Scalar> > diag = thyM->getDiag();
327 RCP<const XpVec> xpDiag;
328 if (!rcp_dynamic_cast<const thyTpV>(diag).
is_null()) {
329 RCP<const tV> tDiag = Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getConstTpetraVector(diag);
330 if (!tDiag.is_null())
333 #ifdef HAVE_MUELU_EPETRA
334 if (xpDiag.is_null()) {
335 RCP<const Epetra_Comm> comm = Thyra::get_Epetra_Comm(*rcp_dynamic_cast<const ThyVSBase>(thyM->range())->getComm());
336 RCP<const Epetra_Map> map = Thyra::get_Epetra_Map(*(thyM->range()), comm);
337 if (!map.is_null()) {
338 RCP<const Epetra_Vector> eDiag = Thyra::get_Epetra_Vector(*map, diag);
339 RCP<Epetra_Vector> nceDiag = rcp_const_cast<
Epetra_Vector>(eDiag);
341 xpDiag = rcp_dynamic_cast<XpVec>(xpEpDiag,
true);
347 paramList.set<RCP<XpMat> >(parameterName, M);
349 }
else if (paramList.isType<RCP<const ThyLinOpBase> >(parameterName)) {
350 RCP<const ThyLinOpBase> thyM = paramList.get<RCP<const ThyLinOpBase> >(parameterName);
351 paramList.remove(parameterName);
353 RCP<XpMat> M = XpThyUtils::toXpetra(Teuchos::rcp_const_cast<ThyLinOpBase>(thyM));
354 paramList.set<RCP<XpMat> >(parameterName, M);
355 }
catch (std::exception& e) {
356 RCP<XpOp> M = XpThyUtils::toXpetraOperator(Teuchos::rcp_const_cast<ThyLinOpBase>(thyM));
360 if (tO->hasDiagonal()) {
361 diag =
rcp(
new tV(tO->getRangeMap()));
362 tO->getLocalDiagCopy(*diag);
366 auto op = rcp_dynamic_cast<XpOp>(tpFOp);
367 paramList.set<RCP<XpOp> >(parameterName, op);
381 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
382 MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MueLuPreconditionerFactory()
383 : paramList_(
rcp(new ParameterList())) {}
387 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
388 bool MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::isCompatible(
const LinearOpSourceBase<Scalar>& fwdOpSrc)
const {
389 const RCP<const LinearOpBase<Scalar> > fwdOp = fwdOpSrc.getOp();
391 if (Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::isTpetra(fwdOp))
return true;
393 #ifdef HAVE_MUELU_EPETRA
394 if (Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::isEpetra(fwdOp))
return true;
397 if (Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::isBlockedOperator(fwdOp))
return true;
402 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
403 RCP<PreconditionerBase<Scalar> > MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::createPrec()
const {
407 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
408 void MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
409 initializePrec(
const RCP<
const LinearOpSourceBase<Scalar> >& fwdOpSrc, PreconditionerBase<Scalar>* prec,
const ESupportSolveUse supportSolveUse)
const {
412 using Teuchos::rcp_dynamic_cast;
418 typedef Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpThyUtils;
424 typedef Thyra::LinearOpBase<Scalar> ThyLinOpBase;
429 #if defined(MUELU_CAN_USE_MIXED_PRECISION)
430 typedef Xpetra::TpetraHalfPrecisionOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpHalfPrecOp;
431 typedef typename XpHalfPrecOp::HalfScalar HalfScalar;
446 ParameterList paramList = *paramList_;
449 const RCP<const ThyLinOpBase> fwdOp = fwdOpSrc->getOp();
453 bool bIsEpetra = XpThyUtils::isEpetra(fwdOp);
454 bool bIsTpetra = XpThyUtils::isTpetra(fwdOp);
455 bool bIsBlocked = XpThyUtils::isBlockedOperator(fwdOp);
460 RCP<XpMat> A = Teuchos::null;
463 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(fwdOp);
473 RCP<XpMat> A00 = XpThyUtils::toXpetra(Teuchos::rcp_const_cast<LinearOpBase<Scalar> >(b00));
476 RCP<const XpMap> rowmap00 = A00->getRowMap();
477 RCP<const Teuchos::Comm<int> > comm = rowmap00->getComm();
480 RCP<XpBlockedCrsMat> bMat =
Teuchos::rcp(
new XpBlockedCrsMat(ThyBlockedOp, comm));
488 A = XpThyUtils::toXpetra(Teuchos::rcp_const_cast<ThyLinOpBase>(fwdOp));
497 RCP<ThyLinOpBase> thyra_precOp = Teuchos::null;
498 thyra_precOp = rcp_dynamic_cast<Thyra::LinearOpBase<Scalar> >(defaultPrec->getNonconstUnspecifiedPrecOp(),
true);
503 const bool startingOver = (thyra_precOp.is_null() || !paramList.isParameter(
"reuse: type") || paramList.get<std::string>(
"reuse: type") ==
"none");
504 bool useHalfPrecision =
false;
505 if (paramList.isParameter(
"half precision"))
506 useHalfPrecision = paramList.get<
bool>(
"half precision");
507 else if (paramList.isSublist(
"Hierarchy") && paramList.sublist(
"Hierarchy").isParameter(
"half precision"))
508 useHalfPrecision = paramList.sublist(
"Hierarchy").get<
bool>(
"half precision");
509 if (useHalfPrecision)
513 if (startingOver ==
true) {
515 std::list<std::string> convertXpetra = {
"Coordinates",
"Nullspace"};
516 for (
auto it = convertXpetra.begin(); it != convertXpetra.end(); ++it)
517 Converters<Scalar, LocalOrdinal, GlobalOrdinal, Node>::replaceWithXpetra(paramList, *it);
519 for (
int lvlNo = 0; lvlNo < 10; ++lvlNo) {
520 if (paramList.isSublist(
"level " + std::to_string(lvlNo) +
" user data")) {
521 ParameterList& lvlList = paramList.sublist(
"level " + std::to_string(lvlNo) +
" user data");
522 std::list<std::string> convertKeys;
523 for (
auto it = lvlList.begin(); it != lvlList.end(); ++it)
524 convertKeys.push_back(lvlList.name(it));
525 for (
auto it = convertKeys.begin(); it != convertKeys.end(); ++it)
526 Converters<Scalar, LocalOrdinal, GlobalOrdinal, Node>::replaceWithXpetra(lvlList, *it);
530 if (useHalfPrecision) {
531 #if defined(MUELU_CAN_USE_MIXED_PRECISION)
538 RCP<XphMat> halfA = Xpetra::convertToHalfPrecision(A);
539 const std::string userName =
"user data";
541 if (userParamList.
isType<RCP<XpmMV> >(
"Coordinates")) {
542 RCP<XpmMV> coords = userParamList.
get<RCP<XpmMV> >(
"Coordinates");
543 userParamList.
remove(
"Coordinates");
544 RCP<XphmMV> halfCoords = Xpetra::convertToHalfPrecision(coords);
545 userParamList.
set(
"Coordinates", halfCoords);
547 if (userParamList.
isType<RCP<XpMV> >(
"Nullspace")) {
548 RCP<XpMV> nullspace = userParamList.
get<RCP<XpMV> >(
"Nullspace");
549 userParamList.
remove(
"Nullspace");
550 RCP<XphMV> halfNullspace = Xpetra::convertToHalfPrecision(nullspace);
551 userParamList.
set(
"Nullspace", halfNullspace);
553 if (paramList.isType<RCP<XpmMV> >(
"Coordinates")) {
554 RCP<XpmMV> coords = paramList.
get<RCP<XpmMV> >(
"Coordinates");
555 paramList.remove(
"Coordinates");
556 RCP<XphmMV> halfCoords = Xpetra::convertToHalfPrecision(coords);
557 userParamList.
set(
"Coordinates", halfCoords);
559 if (paramList.isType<RCP<XpMV> >(
"Nullspace")) {
560 RCP<XpMV> nullspace = paramList.
get<RCP<XpMV> >(
"Nullspace");
561 paramList.remove(
"Nullspace");
562 RCP<XphMV> halfNullspace = Xpetra::convertToHalfPrecision(nullspace);
563 userParamList.
set(
"Nullspace", halfNullspace);
569 RCP<MueLuHalfXpOp> xpOp =
rcp(
new MueLuHalfXpOp(H));
570 xpPrecOp =
rcp(
new XpHalfPrecOp(xpOp));
575 const std::string userName =
"user data";
577 if (paramList.isType<RCP<XpmMV> >(
"Coordinates")) {
578 RCP<XpmMV> coords = paramList.
get<RCP<XpmMV> >(
"Coordinates");
579 paramList.remove(
"Coordinates");
580 userParamList.
set(
"Coordinates", coords);
582 if (paramList.isType<RCP<XpMV> >(
"Nullspace")) {
583 RCP<XpMV> nullspace = paramList.
get<RCP<XpMV> >(
"Nullspace");
584 paramList.remove(
"Nullspace");
585 userParamList.
set(
"Nullspace", nullspace);
590 xpPrecOp =
rcp(
new MueLuXpOp(H));
594 RCP<ThyXpOp> thyXpOp = rcp_dynamic_cast<ThyXpOp>(thyra_precOp,
true);
595 xpPrecOp = rcp_dynamic_cast<XpOp>(thyXpOp->getXpetraOperator(),
true);
596 #if defined(MUELU_CAN_USE_MIXED_PRECISION)
597 RCP<XpHalfPrecOp> xpHalfPrecOp = rcp_dynamic_cast<XpHalfPrecOp>(xpPrecOp);
598 if (!xpHalfPrecOp.is_null()) {
599 RCP<MueLu::Hierarchy<HalfScalar, LocalOrdinal, GlobalOrdinal, Node> > H = rcp_dynamic_cast<MueLuHalfXpOp>(xpHalfPrecOp->GetHalfPrecisionOperator(),
true)->GetHierarchy();
600 RCP<XphMat> halfA = Xpetra::convertToHalfPrecision(A);
603 "Thyra::MueLuPreconditionerFactory: Hierarchy has no levels in it");
605 "Thyra::MueLuPreconditionerFactory: Hierarchy has no fine level operator");
606 RCP<MueLu::Level> level0 = H->GetLevel(0);
607 RCP<XpHalfOp> O0 = level0->Get<RCP<XpHalfOp> >(
"A");
608 RCP<XphMat> A0 = rcp_dynamic_cast<XphMat>(O0,
true);
614 halfA->SetFixedBlockSize(A0->GetFixedBlockSize());
618 level0->Set(
"A", halfA);
625 RCP<MueLuXpOp> xpOp = rcp_dynamic_cast<MueLuXpOp>(thyXpOp->getXpetraOperator(),
true);
626 RCP<MueLu::Hierarchy<Scalar, LocalOrdinal, GlobalOrdinal, Node> > H = xpOp->GetHierarchy();
630 "Thyra::MueLuPreconditionerFactory: Hierarchy has no levels in it");
632 "Thyra::MueLuPreconditionerFactory: Hierarchy has no fine level operator");
633 RCP<MueLu::Level> level0 = H->GetLevel(0);
634 RCP<XpOp> O0 = level0->Get<RCP<XpOp> >(
"A");
635 RCP<XpMat> A0 = rcp_dynamic_cast<XpMat>(O0);
641 A->SetFixedBlockSize(A0->GetFixedBlockSize());
652 RCP<const VectorSpaceBase<Scalar> > thyraRangeSpace = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyra(xpPrecOp->getRangeMap());
653 RCP<const VectorSpaceBase<Scalar> > thyraDomainSpace = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyra(xpPrecOp->getDomainMap());
655 RCP<ThyLinOpBase> thyraPrecOp = Thyra::xpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(thyraRangeSpace, thyraDomainSpace, xpPrecOp);
658 defaultPrec->initializeUnspecified(thyraPrecOp);
661 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
662 void MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
663 uninitializePrec(PreconditionerBase<Scalar>* prec, RCP<
const LinearOpSourceBase<Scalar> >* fwdOp, ESupportSolveUse* supportSolveUse)
const {
672 *fwdOp = Teuchos::null;
675 if (supportSolveUse) {
677 *supportSolveUse = Thyra::SUPPORT_SOLVE_UNSPECIFIED;
680 defaultPrec->uninitialize();
684 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
685 void MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::setParameterList(RCP<ParameterList>
const& paramList) {
687 paramList_ = paramList;
690 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
691 RCP<ParameterList> MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getNonconstParameterList() {
695 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
696 RCP<ParameterList> MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::unsetParameterList() {
697 RCP<ParameterList> savedParamList = paramList_;
698 paramList_ = Teuchos::null;
699 return savedParamList;
702 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
703 RCP<const ParameterList> MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getParameterList()
const {
707 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
708 RCP<const ParameterList> MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getValidParameters()
const {
709 static RCP<const ParameterList> validPL;
712 validPL =
rcp(
new ParameterList());
718 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
719 std::string MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::description()
const {
720 return "Thyra::MueLuPreconditionerFactory";
724 #endif // HAVE_MUELU_STRATIMIKOS
726 #endif // ifdef THYRA_MUELU_PRECONDITIONER_FACTORY_DEF_HPP
MueLu::DefaultLocalOrdinal LocalOrdinal
bool is_null(const boost::shared_ptr< T > &p)
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
bool nonnull(const std::shared_ptr< T > &p)
bool is_null(const std::shared_ptr< T > &p)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static RCP< Time > getNewTimer(const std::string &name)
Teuchos::RCP< MueLu::Hierarchy< Scalar, LocalOrdinal, GlobalOrdinal, Node > > CreateXpetraPreconditioner(Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node >> op, const Teuchos::ParameterList &inParamList)
Helper function to create a MueLu preconditioner that can be used by Xpetra.Given an Xpetra::Matrix...
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
bool remove(std::string const &name, bool throwIfNotExists=true)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultScalar Scalar
Concrete Thyra::LinearOpBase subclass for Xpetra::Operator.
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)
bool isType(const std::string &name) const
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
static RCP< Matrix > Build(const RCP< const Map > &rowMap, size_t maxNumEntriesPerRow, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Exception throws to report errors in the internal logical of the program.
#define TEUCHOS_ASSERT(assertion_test)
RCP< Tpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getOperator()
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
Wraps an existing MueLu::Hierarchy as a Xpetra::Operator.