10 #include "Teko_StridedTpetraOperator.hpp"
11 #include "Teko_TpetraStridedMappingStrategy.hpp"
12 #include "Teko_TpetraReorderedMappingStrategy.hpp"
14 #include "Teuchos_VerboseObject.hpp"
16 #include "Thyra_LinearOpBase.hpp"
17 #include "Thyra_TpetraLinearOp.hpp"
18 #include "Thyra_TpetraThyraWrappers.hpp"
19 #include "Thyra_DefaultProductMultiVector.hpp"
20 #include "Thyra_DefaultProductVectorSpace.hpp"
21 #include "Thyra_DefaultBlockedLinearOp.hpp"
23 #include "Tpetra_Vector.hpp"
24 #include "MatrixMarket_Tpetra.hpp"
29 namespace TpetraHelpers {
33 using Teuchos::rcp_dynamic_cast;
35 StridedTpetraOperator::StridedTpetraOperator(
36 int numVars,
const Teuchos::RCP<
const Tpetra::Operator<ST, LO, GO, NT> >& content,
37 const std::string& label)
38 : Teko::TpetraHelpers::TpetraOperatorWrapper(), label_(label) {
39 std::vector<int> vars;
42 for (
int i = 0; i < numVars; i++) vars.push_back(1);
44 SetContent(vars, content);
47 StridedTpetraOperator::StridedTpetraOperator(
48 const std::vector<int>& vars,
49 const Teuchos::RCP<
const Tpetra::Operator<ST, LO, GO, NT> >& content,
const std::string& label)
50 : Teko::TpetraHelpers::TpetraOperatorWrapper(), label_(label) {
51 SetContent(vars, content);
54 void StridedTpetraOperator::SetContent(
55 const std::vector<int>& vars,
56 const Teuchos::RCP<
const Tpetra::Operator<ST, LO, GO, NT> >& content) {
57 fullContent_ = content;
58 stridedMapping_ = rcp(
new TpetraStridedMappingStrategy(vars, fullContent_->getDomainMap(),
59 *fullContent_->getDomainMap()->getComm()));
60 SetMapStrategy(stridedMapping_);
63 BuildBlockedOperator();
66 void StridedTpetraOperator::BuildBlockedOperator() {
67 TEUCHOS_ASSERT(stridedMapping_ != Teuchos::null);
70 const RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > crsContent =
71 rcp_dynamic_cast<
const Tpetra::CrsMatrix<ST, LO, GO, NT> >(fullContent_);
74 if (stridedOperator_ == Teuchos::null) {
75 stridedOperator_ = stridedMapping_->buildBlockedThyraOp(crsContent, label_);
77 const RCP<Thyra::BlockedLinearOpBase<ST> > blkOp =
78 rcp_dynamic_cast<Thyra::BlockedLinearOpBase<ST> >(stridedOperator_,
true);
79 stridedMapping_->rebuildBlockedThyraOp(crsContent, blkOp);
83 SetOperator(stridedOperator_,
false);
86 if (reorderManager_ != Teuchos::null) Reorder(*reorderManager_);
89 const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> > StridedTpetraOperator::GetBlock(
91 const RCP<const Thyra::BlockedLinearOpBase<ST> > blkOp =
92 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<ST> >(getThyraOp());
94 RCP<const Thyra::TpetraLinearOp<ST, LO, GO, NT> > tOp =
95 rcp_dynamic_cast<
const Thyra::TpetraLinearOp<ST, LO, GO, NT> >(blkOp->getBlock(i, j),
true);
96 return tOp->getConstTpetraOperator();
102 void StridedTpetraOperator::Reorder(
const BlockReorderManager& brm) {
103 reorderManager_ = rcp(
new BlockReorderManager(brm));
106 RCP<const MappingStrategy> reorderMapping =
107 rcp(
new TpetraReorderedMappingStrategy(*reorderManager_, stridedMapping_));
108 RCP<const Thyra::BlockedLinearOpBase<ST> > blockOp =
109 rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<ST> >(stridedOperator_);
111 RCP<const Thyra::LinearOpBase<ST> > A = buildReorderedLinearOp(*reorderManager_, blockOp);
114 SetMapStrategy(reorderMapping);
115 SetOperator(A,
false);
119 void StridedTpetraOperator::RemoveReording() {
120 SetMapStrategy(stridedMapping_);
121 SetOperator(stridedOperator_,
false);
122 reorderManager_ = Teuchos::null;
127 void StridedTpetraOperator::WriteBlocks(
const std::string& prefix)
const {
128 RCP<Thyra::PhysicallyBlockedLinearOpBase<ST> > blockOp =
129 rcp_dynamic_cast<Thyra::PhysicallyBlockedLinearOpBase<ST> >(stridedOperator_);
132 int rows = Teko::blockRowCount(blockOp);
134 for (
int i = 0; i < rows; i++) {
135 for (
int j = 0; j < rows; j++) {
137 RCP<const Thyra::TpetraLinearOp<ST, LO, GO, NT> > tOp =
138 rcp_dynamic_cast<
const Thyra::TpetraLinearOp<ST, LO, GO, NT> >(blockOp->getBlock(i, j));
139 RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > mat =
140 Teuchos::rcp_dynamic_cast<
const Tpetra::CrsMatrix<ST, LO, GO, NT> >(
141 tOp->getConstTpetraOperator());
144 Tpetra::MatrixMarket::Writer<Tpetra::CrsMatrix<ST, LO, GO, NT> >::writeSparseFile(
145 formatBlockName(prefix, i, j, rows).c_str(), mat);
157 std::string StridedTpetraOperator::PrintNorm(
const eNormType& nrmType,
const char newline) {
158 BlockedLinearOp blockOp = toBlockedLinearOp(stridedOperator_);
161 int rowCount = Teko::blockRowCount(blockOp);
162 int colCount = Teko::blockRowCount(blockOp);
164 std::stringstream ss;
166 ss << std::scientific;
167 for (
int row = 0; row < rowCount; row++) {
168 for (
int col = 0; col < colCount; col++) {
170 RCP<const Thyra::TpetraLinearOp<ST, LO, GO, NT> > Aij =
171 rcp_dynamic_cast<
const Thyra::TpetraLinearOp<ST, LO, GO, NT> >(
172 blockOp->getBlock(row, col),
true);
173 RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > mat =
174 Teuchos::rcp_dynamic_cast<
const Tpetra::CrsMatrix<ST, LO, GO, NT> >(
175 Aij->getConstTpetraOperator(),
true);
186 case Frobenius: norm = mat->getFrobeniusNorm();
break;
188 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
189 "StridedTpetraOperator::NormType incorrectly specified. Only "
190 "Frobenius norm implemented for Tpetra matrices.");
201 bool StridedTpetraOperator::testAgainstFullOperator(
int count, ST tol)
const {
202 Tpetra::Vector<ST, LO, GO, NT> xf(getRangeMap());
203 Tpetra::Vector<ST, LO, GO, NT> xs(getRangeMap());
204 Tpetra::Vector<ST, LO, GO, NT> y(getDomainMap());
208 ST diffNorm = 0.0, trueNorm = 0.0;
209 for (
int i = 0; i < count; i++) {
216 fullContent_->apply(y, xf);
219 xs.update(-1.0, xf, 1.0);
220 diffNorm = xs.norm2();
221 trueNorm = xf.norm2();
224 result &= (diffNorm / trueNorm < tol);