10#include "Teko_TpetraHelpers.hpp"
11#include "Teko_ConfigDefs.hpp"
14#include "Thyra_BlockedLinearOpBase.hpp"
15#include "Thyra_DefaultMultipliedLinearOp.hpp"
16#include "Thyra_DefaultDiagonalLinearOp.hpp"
17#include "Thyra_DefaultZeroLinearOp.hpp"
18#include "Thyra_DefaultBlockedLinearOp.hpp"
20#include "Thyra_SpmdVectorBase.hpp"
21#include "Thyra_SpmdVectorSpaceBase.hpp"
22#include "Thyra_ScalarProdVectorSpaceBase.hpp"
28#include "Thyra_TpetraLinearOp.hpp"
29#include "Thyra_TpetraMultiVector.hpp"
30#include "Tpetra_CrsMatrix.hpp"
31#include "Tpetra_Vector.hpp"
32#include "Thyra_TpetraThyraWrappers.hpp"
33#include "TpetraExt_MatrixMatrix.hpp"
34#include "Tpetra_RowMatrixTransposer.hpp"
39using Teuchos::rcp_dynamic_cast;
40using Teuchos::rcpFromRef;
43namespace TpetraHelpers {
55const Teuchos::RCP<const Thyra::LinearOpBase<ST> > thyraDiagOp(
56 const RCP<
const Tpetra::Vector<ST, LO, GO, NT> >& tv,
const Tpetra::Map<LO, GO, NT>& map,
57 const std::string& lbl) {
58 const RCP<const Thyra::VectorBase<ST> > thyraVec
59 = Thyra::createConstVector<ST, LO, GO, NT>(
60 tv, Thyra::createVectorSpace<ST, LO, GO, NT>(rcpFromRef(map)));
61 Teuchos::RCP<Thyra::LinearOpBase<ST> > op =
62 Teuchos::rcp(
new Thyra::DefaultDiagonalLinearOp<ST>(thyraVec));
63 op->setObjectLabel(lbl);
77const Teuchos::RCP<Thyra::LinearOpBase<ST> > thyraDiagOp(
78 const RCP<Tpetra::Vector<ST, LO, GO, NT> >& tv,
const Tpetra::Map<LO, GO, NT>& map,
79 const std::string& lbl) {
80 const RCP<Thyra::VectorBase<ST> > thyraVec
81 = Thyra::createVector<ST, LO, GO, NT>(
82 tv, Thyra::createVectorSpace<ST, LO, GO, NT>(rcpFromRef(map)));
83 Teuchos::RCP<Thyra::LinearOpBase<ST> > op =
84 Teuchos::rcp(
new Thyra::DefaultDiagonalLinearOp<ST>(thyraVec));
85 op->setObjectLabel(lbl);
98void fillDefaultSpmdMultiVector(Teuchos::RCP<Thyra::TpetraMultiVector<ST, LO, GO, NT> >& spmdMV,
99 Teuchos::RCP<Tpetra::MultiVector<ST, LO, GO, NT> >& tpetraMV) {
102 const RCP<Thyra::TpetraVectorSpace<ST, LO, GO, NT> > range =
103 Thyra::tpetraVectorSpace<ST, LO, GO, NT>(tpetraMV->getMap());
104 const RCP<const Thyra::ScalarProdVectorSpaceBase<ST> > domain =
105 rcp_dynamic_cast<const Thyra::ScalarProdVectorSpaceBase<ST> >(spmdMV->domain());
107 TEUCHOS_ASSERT((
size_t)domain->dim() == tpetraMV->getNumVectors());
110 if (!tpetraMV->isConstantStride())
111 TEUCHOS_TEST_FOR_EXCEPT(
true);
114 spmdMV->initialize(range, domain, tpetraMV);
117 Teuchos::set_extra_data<RCP<Tpetra::MultiVector<ST, LO, GO, NT> > >(
118 tpetraMV,
"Tpetra::MultiVector", Teuchos::outArg(spmdMV));
130void identityRowIndices(
const Tpetra::Map<LO, GO, NT>& rowMap,
131 const Tpetra::CrsMatrix<ST, LO, GO, NT>& mat, std::vector<GO>& outIndices) {
133 for (
size_t i = 0; i < rowMap.getLocalNumElements(); i++) {
134 bool rowIsIdentity =
true;
135 GO rowGID = rowMap.getGlobalElement(i);
137 size_t numEntries = mat.getNumEntriesInGlobalRow(i);
138 auto indices =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_global_inds_host_view_type(
139 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), numEntries);
140 auto values =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_values_host_view_type(
141 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), numEntries);
143 mat.getGlobalRowCopy(rowGID, indices, values, numEntries);
146 for (
size_t j = 0; j < numEntries; j++) {
147 GO colGID = indices(j);
150 if (colGID == rowGID)
151 rowIsIdentity &= values(j) == 1.0;
153 rowIsIdentity &= values(j) == 0.0;
156 if (not rowIsIdentity)
break;
160 if (rowIsIdentity) outIndices.push_back(rowGID);
174void zeroMultiVectorRowIndices(Tpetra::MultiVector<ST, LO, GO, NT>& mv,
175 const std::vector<GO>& zeroIndices) {
176 LO colCnt = mv.getNumVectors();
177 std::vector<GO>::const_iterator itr;
180 for (itr = zeroIndices.begin(); itr != zeroIndices.end(); ++itr) {
182 for (
int j = 0; j < colCnt; j++) mv.replaceGlobalValue(*itr, j, 0.0);
196 const Teuchos::RCP<
const Tpetra::Operator<ST, LO, GO, NT> >& op)
197 : zeroIndices_(zeroIndices), tpetraOp_(op) {}
201 Tpetra::MultiVector<ST, LO, GO, NT>& Y, Teuchos::ETransp mode, ST alpha,
209 tpetraOp_->apply(X, Y, mode, alpha, beta);
212 zeroMultiVectorRowIndices(Y, zeroIndices_);
215bool isTpetraLinearOp(
const LinearOp& op) {
217 RCP<const Thyra::TpetraLinearOp<ST, LO, GO, NT> > tOp =
218 rcp_dynamic_cast<const Thyra::TpetraLinearOp<ST, LO, GO, NT> >(op);
219 if (!tOp.is_null())
return true;
223 Thyra::EOpTransp transp = Thyra::NOTRANS;
224 RCP<const Thyra::LinearOpBase<ST> > wrapped_op;
225 Thyra::unwrap(op, &scalar, &transp, &wrapped_op);
226 tOp = rcp_dynamic_cast<const Thyra::TpetraLinearOp<ST, LO, GO, NT> >(wrapped_op);
227 if (!tOp.is_null())
return true;
232RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > getTpetraCrsMatrix(
const LinearOp& op, ST* scalar,
235 RCP<const Thyra::TpetraLinearOp<ST, LO, GO, NT> > tOp =
236 rcp_dynamic_cast<const Thyra::TpetraLinearOp<ST, LO, GO, NT> >(op);
237 if (!tOp.is_null()) {
238 RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > matrix =
239 rcp_dynamic_cast<const Tpetra::CrsMatrix<ST, LO, GO, NT> >(tOp->getConstTpetraOperator(),
247 RCP<const Thyra::LinearOpBase<ST> > wrapped_op;
248 Thyra::EOpTransp eTransp = Thyra::NOTRANS;
249 Thyra::unwrap(op, scalar, &eTransp, &wrapped_op);
250 tOp = rcp_dynamic_cast<const Thyra::TpetraLinearOp<ST, LO, GO, NT> >(wrapped_op,
true);
251 if (!tOp.is_null()) {
252 RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > matrix =
253 rcp_dynamic_cast<const Tpetra::CrsMatrix<ST, LO, GO, NT> >(tOp->getConstTpetraOperator(),
256 if (eTransp == Thyra::NOTRANS) *transp =
false;
260 return Teuchos::null;
263RCP<Tpetra::CrsMatrix<ST, LO, GO, NT> > materializeTpetraCrsMatrix(
const LinearOp& op) {
266 auto tCrsOp = getTpetraCrsMatrix(op, &scalar, &transp);
267 auto explicitCrsOp = transp
268 ? Tpetra::RowMatrixTransposer<ST, LO, GO, NT>(tCrsOp).createTranspose()
269 : rcp(
new Tpetra::CrsMatrix<ST, LO, GO, NT>(*tCrsOp, Teuchos::Copy));
270 if (scalar != Teuchos::ScalarTraits<ST>::one()) explicitCrsOp->scale(scalar);
271 return explicitCrsOp;
274ModifiableLinearOp materializeTpetraLinearOp(
const LinearOp& op,
const ModifiableLinearOp& destOp) {
275 auto explicitCrsOp = materializeTpetraCrsMatrix(op);
277 RCP<Thyra::LinearOpBase<ST> > explicitOp;
278 if (destOp != Teuchos::null)
281 explicitOp = rcp(
new Thyra::TpetraLinearOp<ST, LO, GO, NT>());
283 auto tExplicitOp = rcp_dynamic_cast<Thyra::TpetraLinearOp<ST, LO, GO, NT> >(explicitOp,
true);
284 tExplicitOp->initialize(Thyra::tpetraVectorSpace<ST, LO, GO, NT>(explicitCrsOp->getRangeMap()),
285 Thyra::tpetraVectorSpace<ST, LO, GO, NT>(explicitCrsOp->getDomainMap()),
void apply(const Tpetra::MultiVector< ST, LO, GO, NT > &X, Tpetra::MultiVector< ST, LO, GO, NT > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, ST alpha=Teuchos::ScalarTraits< ST >::one(), ST beta=Teuchos::ScalarTraits< ST >::zero()) const
Perform a matrix-vector product with certain rows zeroed out.
ZeroedOperator(const std::vector< GO > &zeroIndices, const Teuchos::RCP< const Tpetra::Operator< ST, LO, GO, NT > > &op)
Constructor for a ZeroedOperator.