// implementation of "toThyra" for full specialization on SC=double, LO=GO=int and NO=EpetraNode // We need the specialization in the cpp file due to a circle dependency in the .hpp files for BlockedCrsMatrix Teuchos::RCP<Thyra::LinearOpBase<double> > ThyraUtils<double, int, int, EpetraNode>::toThyra(const Teuchos::RCP<Xpetra::BlockedCrsMatrix<double, int, int, EpetraNode> >& mat) { int nRows = mat->Rows(); int nCols = mat->Cols(); Teuchos::RCP<Xpetra::Matrix<double, int, int, EpetraNode> > Ablock = mat->getMatrix(0,0); Teuchos::RCP<Xpetra::CrsMatrixWrap<double, int, int, EpetraNode> > Ablock_wrap = Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<double, int, int, EpetraNode>>(Ablock); TEUCHOS_TEST_FOR_EXCEPT(Ablock_wrap.is_null() == true); bool bTpetra = false; bool bEpetra = false; #ifdef HAVE_XPETRA_TPETRA // Note: Epetra is enabled #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > tpetraMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(Ablock_wrap->getCrsMatrix()); if(tpetraMat!=Teuchos::null) bTpetra = true; #else bTpetra = false; #endif #endif #ifdef HAVE_XPETRA_EPETRA Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node> > epetraMat = Teuchos::rcp_dynamic_cast<Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node> >(Ablock_wrap->getCrsMatrix()); if(epetraMat!=Teuchos::null) bEpetra = true; #endif TEUCHOS_TEST_FOR_EXCEPT(bTpetra == bEpetra); // we only allow Epetra OR Tpetra // create new Thyra blocked operator Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<Scalar> > blockMat = Thyra::defaultBlockedLinearOp<Scalar>(); blockMat->beginBlockFill(nRows,nCols); for (int r=0; r<nRows; ++r) { for (int c=0; c<nCols; ++c) { Teuchos::RCP<Matrix> xpmat = mat->getMatrix(r,c); Teuchos::RCP<CrsMatrixWrap> xpwrap = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(xpmat); TEUCHOS_TEST_FOR_EXCEPT(xpwrap.is_null() == true); Teuchos::RCP<Thyra::LinearOpBase<Scalar> > thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix()); std::stringstream label; label << "A" << r << c; blockMat->setBlock(r,c,thBlock); } } blockMat->endBlockFill(); return blockMat; }
// implementation of "toThyra" for full specialization on SC=double, LO=GO=int and NO=EpetraNode // We need the specialization in the cpp file due to a circle dependency in the .hpp files for BlockedCrsMatrix Teuchos::RCP<Thyra::LinearOpBase<double> > ThyraUtils<double, int, int, EpetraNode>::toThyra(const Teuchos::RCP<Xpetra::BlockedCrsMatrix<double, int, int, EpetraNode> >& mat) { int nRows = mat->Rows(); int nCols = mat->Cols(); Teuchos::RCP<Xpetra::Matrix<double, int, int, EpetraNode> > Ablock = mat->getInnermostCrsMatrix(); Teuchos::RCP<Xpetra::CrsMatrixWrap<double, int, int, EpetraNode> > Ablock_wrap = Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<double, int, int, EpetraNode>>(Ablock); TEUCHOS_TEST_FOR_EXCEPT(Ablock_wrap.is_null() == true); bool bTpetra = false; bool bEpetra = false; #ifdef HAVE_XPETRA_TPETRA // Note: Epetra is enabled #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > tpetraMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(Ablock_wrap->getCrsMatrix()); if(tpetraMat!=Teuchos::null) bTpetra = true; #else bTpetra = false; #endif #endif #ifdef HAVE_XPETRA_EPETRA Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node> > epetraMat = Teuchos::rcp_dynamic_cast<Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node> >(Ablock_wrap->getCrsMatrix()); if(epetraMat!=Teuchos::null) bEpetra = true; #endif TEUCHOS_TEST_FOR_EXCEPT(bTpetra == bEpetra); // we only allow Epetra OR Tpetra // create new Thyra blocked operator Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<Scalar> > blockMat = Thyra::defaultBlockedLinearOp<Scalar>(); blockMat->beginBlockFill(nRows,nCols); for (int r=0; r<nRows; ++r) { for (int c=0; c<nCols; ++c) { Teuchos::RCP<Matrix> xpmat = mat->getMatrix(r,c); if(xpmat == Teuchos::null) continue; // shortcut for empty blocks Teuchos::RCP<Thyra::LinearOpBase<Scalar> > thBlock = Teuchos::null; // check whether the subblock is again a blocked operator Teuchos::RCP<BlockedCrsMatrix> xpblock = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(xpmat); if(xpblock != Teuchos::null) { if(xpblock->Rows() == 1 && xpblock->Cols() == 1) { // If it is a single block operator, unwrap it Teuchos::RCP<CrsMatrixWrap> xpwrap = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(xpblock->getCrsMatrix()); TEUCHOS_TEST_FOR_EXCEPT(xpwrap.is_null() == true); thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix()); } else { // recursive call for general blocked operators thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpblock); } } else { // check whether it is a CRSMatrix object Teuchos::RCP<CrsMatrixWrap> xpwrap = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(xpmat); TEUCHOS_TEST_FOR_EXCEPT(xpwrap.is_null() == true); thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix()); } blockMat->setBlock(r,c,thBlock); } } blockMat->endBlockFill(); return blockMat; }