void ParameterWidget::appendValue(ParameterList &pParams) { QMapIterator<int, QPair<QString, QVariant> > i(_filterValues); while (i.hasNext()) { i.next(); QPair<QString, QVariant> tempPair = i.value(); if (pParams.inList(tempPair.first)) { pParams.remove(tempPair.first); } pParams.append(tempPair.first, tempPair.second); } }
Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > &inA, Teuchos::ParameterList& inParamList, const Teuchos::RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node>>& inCoords = Teuchos::null, const Teuchos::RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& inNullspace = Teuchos::null) { typedef Scalar SC; typedef LocalOrdinal LO; typedef GlobalOrdinal GO; typedef Node NO; using Teuchos::ParameterList; typedef Xpetra::MultiVector<SC,LO,GO,NO> MultiVector; typedef Xpetra::Matrix<SC,LO,GO,NO> Matrix; typedef Hierarchy<SC,LO,GO,NO> Hierarchy; typedef HierarchyManager<SC,LO,GO,NO> HierarchyManager; typedef Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> crs_matrix_type; typedef Tpetra::Experimental::BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> block_crs_matrix_type; bool hasParamList = inParamList.numParams(); RCP<HierarchyManager> mueLuFactory; ParameterList paramList = inParamList; RCP<const crs_matrix_type> constCrsA; RCP<crs_matrix_type> crsA; #if defined(HAVE_MUELU_EXPERIMENTAL) and defined(HAVE_MUELU_AMGX) std::string externalMG = "use external multigrid package"; if (hasParamList && paramList.isParameter(externalMG) && paramList.get<std::string>(externalMG) == "amgx"){ constCrsA = rcp_dynamic_cast<const crs_matrix_type>(inA); TEUCHOS_TEST_FOR_EXCEPTION(constCrsA == Teuchos::null, Exceptions::RuntimeError, "CreateTpetraPreconditioner: failed to dynamic cast to Tpetra::CrsMatrix, which is required to be able to use AmgX."); return rcp(new AMGXOperator<SC,LO,GO,NO>(inA,inParamList)); } #endif std::string syntaxStr = "parameterlist: syntax"; if (hasParamList && paramList.isParameter(syntaxStr) && paramList.get<std::string>(syntaxStr) == "ml") { paramList.remove(syntaxStr); mueLuFactory = rcp(new MLParameterListInterpreter<SC,LO,GO,NO>(paramList)); } else { mueLuFactory = rcp(new ParameterListInterpreter <SC,LO,GO,NO>(paramList,inA->getDomainMap()->getComm())); } RCP<Hierarchy> H = mueLuFactory->CreateHierarchy(); H->setlib(Xpetra::UseTpetra); // Wrap A RCP<Matrix> A; RCP<block_crs_matrix_type> bcrsA = rcp_dynamic_cast<block_crs_matrix_type>(inA); crsA = rcp_dynamic_cast<crs_matrix_type>(inA); if (crsA != Teuchos::null) A = TpetraCrs_To_XpetraMatrix<SC,LO,GO,NO>(crsA); else if (bcrsA != Teuchos::null) { RCP<Xpetra::CrsMatrix<SC,LO,GO,NO> > temp = rcp(new Xpetra::TpetraBlockCrsMatrix<SC,LO,GO,NO>(bcrsA)); TEUCHOS_TEST_FOR_EXCEPTION(temp==Teuchos::null, Exceptions::RuntimeError, "CreateTpetraPreconditioner: cast from Tpetra::Experimental::BlockCrsMatrix to Xpetra::TpetraBlockCrsMatrix failed."); A = rcp(new Xpetra::CrsMatrixWrap<SC,LO,GO,NO>(temp)); } else { TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "CreateTpetraPreconditioner: only Tpetra CrsMatrix and BlockCrsMatrix types are supported."); } H->GetLevel(0)->Set("A", A); // Wrap coordinates if available if (inCoords != Teuchos::null) { RCP<Xpetra::MultiVector<double,LO,GO,NO> > coordinates = TpetraMultiVector_To_XpetraMultiVector<double,LO,GO,NO>(inCoords); H->GetLevel(0)->Set("Coordinates", coordinates); } // Wrap nullspace if available, otherwise use constants RCP<MultiVector> nullspace; if (inNullspace != Teuchos::null) { nullspace = TpetraMultiVector_To_XpetraMultiVector<SC,LO,GO,NO>(inNullspace); } else { int nPDE = MasterList::getDefault<int>("number of equations"); if (paramList.isSublist("Matrix")) { // Factory style parameter list const Teuchos::ParameterList& operatorList = paramList.sublist("Matrix"); if (operatorList.isParameter("PDE equations")) nPDE = operatorList.get<int>("PDE equations"); } else if (paramList.isParameter("number of equations")) { // Easy style parameter list nPDE = paramList.get<int>("number of equations"); } nullspace = Xpetra::MultiVectorFactory<SC,LO,GO,NO>::Build(A->getDomainMap(), nPDE); if (nPDE == 1) { nullspace->putScalar(Teuchos::ScalarTraits<SC>::one()); } else { for (int i = 0; i < nPDE; i++) { Teuchos::ArrayRCP<SC> nsData = nullspace->getDataNonConst(i); for (int j = 0; j < nsData.size(); j++) { GO GID = A->getDomainMap()->getGlobalElement(j) - A->getDomainMap()->getIndexBase(); if ((GID-i) % nPDE == 0) nsData[j] = Teuchos::ScalarTraits<SC>::one(); } } } } H->GetLevel(0)->Set("Nullspace", nullspace); Teuchos::ParameterList nonSerialList,dummyList; ExtractNonSerializableData(paramList, dummyList, nonSerialList); HierarchyUtils<SC,LO,GO,NO>::AddNonSerializableDataToHierarchy(*mueLuFactory,*H, nonSerialList); mueLuFactory->SetupHierarchy(*H); return rcp(new TpetraOperator<SC,LO,GO,NO>(H)); }
Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::CrsMatrix <Scalar, LocalOrdinal, GlobalOrdinal, Node> >& inA, Teuchos::ParameterList& paramListIn, const Teuchos::RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node> >& inCoords = Teuchos::null, const Teuchos::RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& inNullspace = Teuchos::null) { typedef Scalar SC; typedef LocalOrdinal LO; typedef GlobalOrdinal GO; typedef Node NO; using Teuchos::ParameterList; typedef Xpetra::MultiVector<SC,LO,GO,NO> MultiVector; typedef Xpetra::Matrix<SC,LO,GO,NO> Matrix; typedef Hierarchy<SC,LO,GO,NO> Hierarchy; typedef HierarchyManager<SC,LO,GO,NO> HierarchyManager; bool hasParamList = paramListIn.numParams(); RCP<HierarchyManager> mueLuFactory; ParameterList paramList = paramListIn; std::string syntaxStr = "parameterlist: syntax"; if (hasParamList && paramList.isParameter(syntaxStr) && paramList.get<std::string>(syntaxStr) == "ml") { paramList.remove(syntaxStr); mueLuFactory = rcp(new MLParameterListInterpreter<SC,LO,GO,NO>(paramList)); } else { mueLuFactory = rcp(new ParameterListInterpreter <SC,LO,GO,NO>(paramList)); } RCP<Hierarchy> H = mueLuFactory->CreateHierarchy(); H->setlib(Xpetra::UseTpetra); // Wrap A RCP<Matrix> A = TpetraCrs_To_XpetraMatrix<SC,LO,GO,NO>(inA); H->GetLevel(0)->Set("A", A); // Wrap coordinates if available if (inCoords != Teuchos::null) { RCP<Xpetra::MultiVector<double,LO,GO,NO> > coordinates = TpetraMultiVector_To_XpetraMultiVector<double,LO,GO,NO>(inCoords); H->GetLevel(0)->Set("Coordinates", coordinates); } // Wrap nullspace if available, otherwise use constants RCP<MultiVector> nullspace; if (inNullspace != Teuchos::null) { nullspace = TpetraMultiVector_To_XpetraMultiVector<SC,LO,GO,NO>(inNullspace); } else { int nPDE = MasterList::getDefault<int>("number of equations"); if (paramList.isSublist("Matrix")) { // Factory style parameter list const Teuchos::ParameterList& operatorList = paramList.sublist("Matrix"); if (operatorList.isParameter("PDE equations")) nPDE = operatorList.get<int>("PDE equations"); } else if (paramList.isParameter("number of equations")) { // Easy style parameter list nPDE = paramList.get<int>("number of equations"); } nullspace = Xpetra::MultiVectorFactory<SC,LO,GO,NO>::Build(A->getDomainMap(), nPDE); if (nPDE == 1) { nullspace->putScalar(Teuchos::ScalarTraits<SC>::one()); } else { for (int i = 0; i < nPDE; i++) { Teuchos::ArrayRCP<SC> nsData = nullspace->getDataNonConst(i); for (int j = 0; j < nsData.size(); j++) { GO GID = A->getDomainMap()->getGlobalElement(j) - A->getDomainMap()->getIndexBase(); if ((GID-i) % nPDE == 0) nsData[j] = Teuchos::ScalarTraits<SC>::one(); } } } } H->GetLevel(0)->Set("Nullspace", nullspace); Teuchos::ParameterList nonSerialList,dummyList; ExtractNonSerializableData(paramList, dummyList, nonSerialList); HierarchyUtils<SC,LO,GO,NO>::AddNonSerializableDataToHierarchy(*mueLuFactory,*H, nonSerialList); mueLuFactory->SetupHierarchy(*H); return rcp(new TpetraOperator<SC,LO,GO,NO>(H)); }
void MueLuPreconditionerFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>:: initializePrec(const RCP<const LinearOpSourceBase<Scalar> >& fwdOpSrc, PreconditionerBase<Scalar>* prec, const ESupportSolveUse supportSolveUse) const { using Teuchos::rcp_dynamic_cast; // we are using typedefs here, since we are using objects from different packages (Xpetra, Thyra,...) typedef Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> XpMap; typedef Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpOp; typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpThyUtils; typedef Xpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpCrsMat; typedef Xpetra::BlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpBlockedCrsMat; typedef Xpetra::Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpMat; typedef Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpMultVec; typedef Xpetra::MultiVector<double,LocalOrdinal,GlobalOrdinal,Node> XpMultVecDouble; typedef Thyra::LinearOpBase<Scalar> ThyLinOpBase; #ifdef HAVE_MUELU_TPETRA typedef MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> MueTpOp; typedef Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpOp; typedef Thyra::TpetraLinearOp<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyTpLinOp; #endif // Check precondition TEUCHOS_ASSERT(Teuchos::nonnull(fwdOpSrc)); TEUCHOS_ASSERT(this->isCompatible(*fwdOpSrc)); TEUCHOS_ASSERT(prec); // Create a copy, as we may remove some things from the list ParameterList paramList = *paramList_; // Retrieve wrapped concrete Xpetra matrix from FwdOp const RCP<const ThyLinOpBase> fwdOp = fwdOpSrc->getOp(); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(fwdOp)); // Check whether it is Epetra/Tpetra bool bIsEpetra = XpThyUtils::isEpetra(fwdOp); bool bIsTpetra = XpThyUtils::isTpetra(fwdOp); bool bIsBlocked = XpThyUtils::isBlockedOperator(fwdOp); TEUCHOS_TEST_FOR_EXCEPT((bIsEpetra == true && bIsTpetra == true)); TEUCHOS_TEST_FOR_EXCEPT((bIsEpetra == bIsTpetra) && bIsBlocked == false); TEUCHOS_TEST_FOR_EXCEPT((bIsEpetra != bIsTpetra) && bIsBlocked == true); RCP<XpMat> A = Teuchos::null; if(bIsBlocked) { Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> > ThyBlockedOp = Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(fwdOp); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(ThyBlockedOp)); TEUCHOS_TEST_FOR_EXCEPT(ThyBlockedOp->blockExists(0,0)==false); Teuchos::RCP<const LinearOpBase<Scalar> > b00 = ThyBlockedOp->getBlock(0,0); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(b00)); RCP<const XpCrsMat > xpetraFwdCrsMat00 = XpThyUtils::toXpetra(b00); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(xpetraFwdCrsMat00)); // MueLu needs a non-const object as input RCP<XpCrsMat> xpetraFwdCrsMatNonConst00 = Teuchos::rcp_const_cast<XpCrsMat>(xpetraFwdCrsMat00); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(xpetraFwdCrsMatNonConst00)); // wrap the forward operator as an Xpetra::Matrix that MueLu can work with RCP<XpMat> A00 = rcp(new Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node>(xpetraFwdCrsMatNonConst00)); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(A00)); RCP<const XpMap> rowmap00 = A00->getRowMap(); RCP< const Teuchos::Comm< int > > comm = rowmap00->getComm(); // create a Xpetra::BlockedCrsMatrix which derives from Xpetra::Matrix that MueLu can work with RCP<XpBlockedCrsMat> bMat = Teuchos::rcp(new XpBlockedCrsMat(ThyBlockedOp, comm)); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(bMat)); // save blocked matrix A = bMat; } else { RCP<const XpCrsMat > xpetraFwdCrsMat = XpThyUtils::toXpetra(fwdOp); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(xpetraFwdCrsMat)); // MueLu needs a non-const object as input RCP<XpCrsMat> xpetraFwdCrsMatNonConst = Teuchos::rcp_const_cast<XpCrsMat>(xpetraFwdCrsMat); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(xpetraFwdCrsMatNonConst)); // wrap the forward operator as an Xpetra::Matrix that MueLu can work with A = rcp(new Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node>(xpetraFwdCrsMatNonConst)); } TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(A)); // Retrieve concrete preconditioner object const Teuchos::Ptr<DefaultPreconditioner<Scalar> > defaultPrec = Teuchos::ptr(dynamic_cast<DefaultPreconditioner<Scalar> *>(prec)); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(defaultPrec)); // extract preconditioner operator RCP<ThyLinOpBase> thyra_precOp = Teuchos::null; thyra_precOp = rcp_dynamic_cast<Thyra::LinearOpBase<Scalar> >(defaultPrec->getNonconstUnspecifiedPrecOp(), true); // Variable for multigrid hierarchy: either build a new one or reuse the existing hierarchy RCP<MueLu::Hierarchy<Scalar,LocalOrdinal,GlobalOrdinal,Node> > H = Teuchos::null; // make a decision whether to (re)build the multigrid preconditioner or reuse the old one // rebuild preconditioner if startingOver == true // reuse preconditioner if startingOver == false const bool startingOver = (thyra_precOp.is_null() || !paramList.isParameter("reuse: type") || paramList.get<std::string>("reuse: type") == "none"); if (startingOver == true) { // extract coordinates from parameter list Teuchos::RCP<XpMultVecDouble> coordinates = Teuchos::null; coordinates = MueLu::Utilities<Scalar,LocalOrdinal,GlobalOrdinal,Node>::ExtractCoordinatesFromParameterList(paramList); // TODO check for Xpetra or Thyra vectors? RCP<XpMultVec> nullspace = Teuchos::null; #ifdef HAVE_MUELU_TPETRA if (bIsTpetra) { typedef Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> tMV; RCP<tMV> tpetra_nullspace = Teuchos::null; if (paramList.isType<Teuchos::RCP<tMV> >("Nullspace")) { tpetra_nullspace = paramList.get<RCP<tMV> >("Nullspace"); paramList.remove("Nullspace"); nullspace = MueLu::TpetraMultiVector_To_XpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(tpetra_nullspace); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(nullspace)); } } #endif // build a new MueLu hierarchy H = MueLu::CreateXpetraPreconditioner(A, paramList, coordinates, nullspace); } else { // reuse old MueLu hierarchy stored in MueLu Tpetra/Epetra operator and put in new matrix // get old MueLu hierarchy #if defined(HAVE_MUELU_TPETRA) if (bIsTpetra) { RCP<ThyTpLinOp> tpetr_precOp = rcp_dynamic_cast<ThyTpLinOp>(thyra_precOp); RCP<MueTpOp> muelu_precOp = rcp_dynamic_cast<MueTpOp>(tpetr_precOp->getTpetraOperator(),true); H = muelu_precOp->GetHierarchy(); } #endif // TODO add the blocked matrix case here... TEUCHOS_TEST_FOR_EXCEPTION(!H->GetNumLevels(), MueLu::Exceptions::RuntimeError, "Thyra::MueLuPreconditionerFactory: Hierarchy has no levels in it"); TEUCHOS_TEST_FOR_EXCEPTION(!H->GetLevel(0)->IsAvailable("A"), MueLu::Exceptions::RuntimeError, "Thyra::MueLuPreconditionerFactory: Hierarchy has no fine level operator"); RCP<MueLu::Level> level0 = H->GetLevel(0); RCP<XpOp> O0 = level0->Get<RCP<XpOp> >("A"); RCP<XpMat> A0 = rcp_dynamic_cast<XpMat>(O0); if (!A0.is_null()) { // If a user provided a "number of equations" argument in a parameter list // during the initial setup, we must honor that settings and reuse it for // all consequent setups. A->SetFixedBlockSize(A0->GetFixedBlockSize()); } // set new matrix level0->Set("A", A); H->SetupRe(); } // wrap hierarchy H in thyraPrecOp RCP<ThyLinOpBase > thyraPrecOp = Teuchos::null; #if defined(HAVE_MUELU_TPETRA) if (bIsTpetra) { RCP<MueTpOp> muelu_tpetraOp = rcp(new MueTpOp(H)); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(muelu_tpetraOp)); RCP<TpOp> tpOp = Teuchos::rcp_dynamic_cast<TpOp>(muelu_tpetraOp); thyraPrecOp = Thyra::createLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpOp); } #endif if(bIsBlocked) { TEUCHOS_TEST_FOR_EXCEPT(Teuchos::nonnull(thyraPrecOp)); typedef MueLu::XpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> MueXpOp; //typedef Thyra::XpetraLinearOp<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyXpLinOp; // unused const RCP<MueXpOp> muelu_xpetraOp = rcp(new MueXpOp(H)); RCP<const VectorSpaceBase<Scalar> > thyraRangeSpace = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(muelu_xpetraOp->getRangeMap()); RCP<const VectorSpaceBase<Scalar> > thyraDomainSpace = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(muelu_xpetraOp->getDomainMap()); RCP <Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > xpOp = Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(muelu_xpetraOp); thyraPrecOp = Thyra::xpetraLinearOp(thyraRangeSpace, thyraDomainSpace,xpOp); } TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thyraPrecOp)); defaultPrec->initializeUnspecified(thyraPrecOp); }