10 #include "Teko_TpetraBlockedMappingStrategy.hpp"
11 #include "Teko_TpetraHelpers.hpp"
13 #include "Thyra_TpetraThyraWrappers.hpp"
14 #include "Thyra_TpetraLinearOp.hpp"
15 #include "Thyra_DefaultProductMultiVector.hpp"
16 #include "Thyra_DefaultProductVectorSpace.hpp"
17 #include "Thyra_DefaultSpmdMultiVector.hpp"
18 #include "Thyra_DefaultBlockedLinearOp.hpp"
22 using Teuchos::rcp_dynamic_cast;
25 namespace TpetraHelpers {
37 TpetraBlockedMappingStrategy::TpetraBlockedMappingStrategy(
38 const std::vector<std::vector<GO>>& vars,
39 const Teuchos::RCP<
const Tpetra::Map<LO, GO, NT>>& map,
const Teuchos::Comm<int>& comm) {
42 buildBlockTransferData(vars, rangeMap_, comm);
53 void TpetraBlockedMappingStrategy::copyTpetraIntoThyra(
54 const Tpetra::MultiVector<ST, LO, GO, NT>& X,
55 const Teuchos::Ptr<Thyra::MultiVectorBase<ST>>& thyra_X)
const {
56 if (blockMaps_.empty()) {
57 auto prod_X = Teuchos::ptr_dynamic_cast<Thyra::ProductMultiVectorBase<ST>>(thyra_X);
58 auto vec = rcp_dynamic_cast<Thyra::TpetraMultiVector<ST, LO, GO, NT>>(
59 prod_X->getNonconstMultiVectorBlock(0),
true);
61 Teuchos::RCP<Tpetra::MultiVector<ST, LO, GO, NT>> X_rcp_nonconst =
62 Teuchos::rcp_const_cast<Tpetra::MultiVector<ST, LO, GO, NT>>(Teuchos::rcpFromRef(X));
63 fillDefaultSpmdMultiVector(vec, X_rcp_nonconst);
67 int count = X.getNumVectors();
69 std::vector<RCP<Tpetra::MultiVector<ST, LO, GO, NT>>> subX;
72 Blocking::buildSubVectors(blockMaps_, subX, count);
75 Blocking::one2many(subX, X, blockImport_);
78 Teuchos::Array<RCP<Thyra::MultiVectorBase<ST>>> thyra_subX;
79 Teuchos::Ptr<Thyra::ProductMultiVectorBase<ST>> prod_X =
80 Teuchos::ptr_dynamic_cast<Thyra::ProductMultiVectorBase<ST>>(thyra_X);
81 for (
unsigned int i = 0; i < blockMaps_.size(); i++) {
82 RCP<Thyra::TpetraMultiVector<ST, LO, GO, NT>> vec =
83 rcp_dynamic_cast<Thyra::TpetraMultiVector<ST, LO, GO, NT>>(
84 prod_X->getNonconstMultiVectorBlock(i),
true);
86 fillDefaultSpmdMultiVector(vec, subX[i]);
98 void TpetraBlockedMappingStrategy::copyThyraIntoTpetra(
99 const RCP<
const Thyra::MultiVectorBase<ST>>& thyra_Y,
100 Tpetra::MultiVector<ST, LO, GO, NT>& Y)
const {
101 if (blockMaps_.empty()) {
102 auto prod_Y = rcp_dynamic_cast<
const Thyra::DefaultProductMultiVector<ST>>(thyra_Y);
103 auto tmv = rcp_dynamic_cast<
const Thyra::TpetraMultiVector<ST, LO, GO, NT>>(
104 prod_Y->getMultiVectorBlock(0),
true)
105 ->getConstTpetraMultiVector();
110 std::vector<RCP<const Tpetra::MultiVector<ST, LO, GO, NT>>> subY;
111 RCP<const Thyra::DefaultProductMultiVector<ST>> prod_Y =
112 rcp_dynamic_cast<
const Thyra::DefaultProductMultiVector<ST>>(thyra_Y);
115 for (
unsigned int i = 0; i < blockMaps_.size(); i++) {
116 RCP<const Thyra::TpetraMultiVector<ST, LO, GO, NT>> tmv =
117 rcp_dynamic_cast<
const Thyra::TpetraMultiVector<ST, LO, GO, NT>>(
118 prod_Y->getMultiVectorBlock(i),
true);
119 subY.push_back(tmv->getConstTpetraMultiVector());
126 Blocking::many2one(Y, subY, blockExport_);
141 void TpetraBlockedMappingStrategy::buildBlockTransferData(
142 const std::vector<std::vector<GO>>& vars,
143 const Teuchos::RCP<
const Tpetra::Map<LO, GO, NT>>& baseMap,
const Teuchos::Comm<int>& comm) {
144 if (vars.size() == 1)
return;
147 for (std::size_t i = 0; i < vars.size(); i++) {
149 Blocking::MapPair mapPair = Blocking::buildSubMap(vars[i], comm);
150 Blocking::ImExPair iePair = Blocking::buildExportImport(*baseMap, mapPair);
152 blockMaps_.push_back(mapPair);
153 blockImport_.push_back(iePair.first);
154 blockExport_.push_back(iePair.second);
168 const Teuchos::RCP<Thyra::BlockedLinearOpBase<ST>>
169 TpetraBlockedMappingStrategy::buildBlockedThyraOp(
170 const RCP<
const Tpetra::CrsMatrix<ST, LO, GO, NT>>& crsContent,
171 const std::string& label)
const {
172 if (blockMaps_.empty()) {
173 RCP<Thyra::DefaultBlockedLinearOp<ST>> A = Thyra::defaultBlockedLinearOp<ST>();
175 auto crsCopy = Teuchos::make_rcp<Tpetra::CrsMatrix<ST, LO, GO, NT>>(*crsContent,
176 Teuchos::DataAccess::View);
178 A->beginBlockFill(1, 1);
181 Thyra::tpetraLinearOp<ST, LO, GO, NT>(
182 Thyra::tpetraVectorSpace<ST, LO, GO, NT>(crsCopy->getRangeMap()),
183 Thyra::tpetraVectorSpace<ST, LO, GO, NT>(crsCopy->getDomainMap()), crsCopy));
189 int dim = blockMaps_.size();
191 plocal2ContigGIDs.resize(dim);
192 for (
int j = 0; j < dim; j++) {
193 plocal2ContigGIDs[j] = Blocking::getSubBlockColumnGIDs(*crsContent, blockMaps_[j]);
196 RCP<Thyra::DefaultBlockedLinearOp<ST>> A = Thyra::defaultBlockedLinearOp<ST>();
198 A->beginBlockFill(dim, dim);
199 for (
int i = 0; i < dim; i++) {
200 for (
int j = 0; j < dim; j++) {
202 std::stringstream ss;
203 ss << label <<
"_" << i <<
"," << j;
206 RCP<Tpetra::CrsMatrix<ST, LO, GO, NT>> blk =
207 Blocking::buildSubBlock(i, j, crsContent, blockMaps_, plocal2ContigGIDs[j]);
208 A->setNonconstBlock(i, j,
209 Thyra::tpetraLinearOp<ST, LO, GO, NT>(
210 Thyra::tpetraVectorSpace<ST, LO, GO, NT>(blk->getRangeMap()),
211 Thyra::tpetraVectorSpace<ST, LO, GO, NT>(blk->getDomainMap()), blk));
229 void TpetraBlockedMappingStrategy::rebuildBlockedThyraOp(
230 const RCP<
const Tpetra::CrsMatrix<ST, LO, GO, NT>>& crsContent,
231 const RCP<Thyra::BlockedLinearOpBase<ST>>& A)
const {
232 if (blockMaps_.empty()) {
233 auto Aij = A->getNonconstBlock(0, 0);
234 auto tAij = rcp_dynamic_cast<Thyra::TpetraLinearOp<ST, LO, GO, NT>>(Aij,
true);
236 rcp_dynamic_cast<Tpetra::CrsMatrix<ST, LO, GO, NT>>(tAij->getTpetraOperator(),
true);
237 auto values_dest = eAij->getLocalMatrixDevice().values;
238 const auto values_src = crsContent->getLocalMatrixDevice().values;
239 TEUCHOS_DEBUG_ASSERT(eAij->getCrsGraph()->isIdenticalTo(*crsContent->getCrsGraph()));
240 TEUCHOS_DEBUG_ASSERT(values_dest.extent(0) == values_src.extent(0));
241 Kokkos::deep_copy(values_dest, values_src);
245 int dim = blockMaps_.size();
247 for (
int i = 0; i < dim; i++) {
248 for (
int j = 0; j < dim; j++) {
250 RCP<Thyra::LinearOpBase<ST>> Aij = A->getNonconstBlock(i, j);
251 RCP<Thyra::TpetraLinearOp<ST, LO, GO, NT>> tAij =
252 rcp_dynamic_cast<Thyra::TpetraLinearOp<ST, LO, GO, NT>>(Aij,
true);
253 RCP<Tpetra::CrsMatrix<ST, LO, GO, NT>> eAij =
254 rcp_dynamic_cast<Tpetra::CrsMatrix<ST, LO, GO, NT>>(tAij->getTpetraOperator(),
true);
257 Blocking::rebuildSubBlock(i, j, crsContent, blockMaps_, *eAij, plocal2ContigGIDs[j]);