Teko Version of the Day
Loading...
Searching...
No Matches
Teko_StridedTpetraOperator.cpp
1// @HEADER
2// *****************************************************************************
3// Teko: A package for block and physics based preconditioning
4//
5// Copyright 2010 NTESS and the Teko contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Teko_StridedTpetraOperator.hpp"
11#include "Teko_TpetraStridedMappingStrategy.hpp"
12#include "Teko_TpetraReorderedMappingStrategy.hpp"
13
14#include "Teuchos_VerboseObject.hpp"
15
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"
22
23#include "Tpetra_Vector.hpp"
24#include "MatrixMarket_Tpetra.hpp"
25
26#include "Teko_Utilities.hpp"
27
28namespace Teko {
29namespace TpetraHelpers {
30
31using Teuchos::RCP;
32using Teuchos::rcp;
33using Teuchos::rcp_dynamic_cast;
34
35StridedTpetraOperator::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;
40
41 // build vector describing the sub maps
42 for (int i = 0; i < numVars; i++) vars.push_back(1);
43
44 SetContent(vars, content);
45}
46
47StridedTpetraOperator::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);
52}
53
54void 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_);
61
62 // build thyra operator
63 BuildBlockedOperator();
64}
65
66void StridedTpetraOperator::BuildBlockedOperator() {
67 TEUCHOS_ASSERT(stridedMapping_ != Teuchos::null);
68
69 // get a CRS matrix
70 const RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > crsContent =
71 rcp_dynamic_cast<const Tpetra::CrsMatrix<ST, LO, GO, NT> >(fullContent_);
72
73 // ask the strategy to build the Thyra operator for you
74 if (stridedOperator_ == Teuchos::null) {
75 stridedOperator_ = stridedMapping_->buildBlockedThyraOp(crsContent, label_);
76 } else {
77 const RCP<Thyra::BlockedLinearOpBase<ST> > blkOp =
78 rcp_dynamic_cast<Thyra::BlockedLinearOpBase<ST> >(stridedOperator_, true);
79 stridedMapping_->rebuildBlockedThyraOp(crsContent, blkOp);
80 }
81
82 // set whatever is returned
83 SetOperator(stridedOperator_, false);
84
85 // reorder if neccessary
86 if (reorderManager_ != Teuchos::null) Reorder(*reorderManager_);
87}
88
89const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> > StridedTpetraOperator::GetBlock(
90 int i, int j) const {
91 const RCP<const Thyra::BlockedLinearOpBase<ST> > blkOp =
92 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<ST> >(getThyraOp());
93
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();
97}
98
102void StridedTpetraOperator::Reorder(const BlockReorderManager& brm) {
103 reorderManager_ = rcp(new BlockReorderManager(brm));
104
105 // build reordered objects
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_);
110
111 RCP<const Thyra::LinearOpBase<ST> > A = buildReorderedLinearOp(*reorderManager_, blockOp);
112
113 // set them as working values
114 SetMapStrategy(reorderMapping);
115 SetOperator(A, false);
116}
117
119void StridedTpetraOperator::RemoveReording() {
120 SetMapStrategy(stridedMapping_);
121 SetOperator(stridedOperator_, false);
122 reorderManager_ = Teuchos::null;
123}
124
127void StridedTpetraOperator::WriteBlocks(const std::string& prefix) const {
128 RCP<Thyra::PhysicallyBlockedLinearOpBase<ST> > blockOp =
129 rcp_dynamic_cast<Thyra::PhysicallyBlockedLinearOpBase<ST> >(stridedOperator_);
130
131 // get size of strided block operator
132 int rows = Teko::blockRowCount(blockOp);
133
134 for (int i = 0; i < rows; i++) {
135 for (int j = 0; j < rows; j++) {
136 // get the row matrix object (Note: can't use "GetBlock" method b/c matrix might be reordered)
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());
142
143 // write to file
144 Tpetra::MatrixMarket::Writer<Tpetra::CrsMatrix<ST, LO, GO, NT> >::writeSparseFile(
145 formatBlockName(prefix, i, j, rows).c_str(), mat);
146 }
147 }
148}
149
157std::string StridedTpetraOperator::PrintNorm(const eNormType& nrmType, const char newline) {
158 BlockedLinearOp blockOp = toBlockedLinearOp(stridedOperator_);
159
160 // get size of strided block operator
161 int rowCount = Teko::blockRowCount(blockOp);
162 int colCount = Teko::blockRowCount(blockOp);
163
164 std::stringstream ss;
165 ss.precision(4);
166 ss << std::scientific;
167 for (int row = 0; row < rowCount; row++) {
168 for (int col = 0; col < colCount; col++) {
169 // get the row matrix object (Note: can't use "GetBlock" method b/c matrix might be reordered)
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);
176
177 // compute the norm
178 ST norm = 0.0;
179 switch (nrmType) {
180 // case Inf:
181 // norm = mat->normInf();
182 // break;
183 // case One:
184 // norm = mat->normOne();
185 // break;
186 case Frobenius: norm = mat->getFrobeniusNorm(); break;
187 default:
188 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
189 "StridedTpetraOperator::NormType incorrectly specified. Only "
190 "Frobenius norm implemented for Tpetra matrices.");
191 }
192
193 ss << norm << " ";
194 }
195 ss << newline;
196 }
197
198 return ss.str();
199}
200
201bool 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());
205
206 // test operator many times
207 bool result = true;
208 ST diffNorm = 0.0, trueNorm = 0.0;
209 for (int i = 0; i < count; i++) {
210 xf.putScalar(0.0);
211 xs.putScalar(0.0);
212 y.randomize();
213
214 // apply operator
215 apply(y, xs); // xs = A*y
216 fullContent_->apply(y, xf); // xf = A*y
217
218 // compute norms
219 xs.update(-1.0, xf, 1.0);
220 diffNorm = xs.norm2();
221 trueNorm = xf.norm2();
222
223 // check result
224 result &= (diffNorm / trueNorm < tol);
225 }
226
227 return result;
228}
229
230} // end namespace TpetraHelpers
231} // end namespace Teko
Implements the Epetra_Operator interface with a Thyra LinearOperator. This enables the use of absrtac...