47 #include "Teko_BlockingTpetra.hpp"
50 #include "Tpetra_Vector.hpp"
51 #include "Tpetra_Map.hpp"
57 namespace TpetraHelpers {
73 const MapPair buildSubMap(
const std::vector<GO>& gid,
const Teuchos::Comm<int>& comm) {
74 using GST = Tpetra::global_size_t;
75 const GST invalid = Teuchos::OrdinalTraits<GST>::invalid();
76 Teuchos::RCP<Tpetra::Map<LO, GO, NT> > gidMap = rcp(
77 new Tpetra::Map<LO, GO, NT>(invalid, Teuchos::ArrayView<const GO>(gid), 0, rcpFromRef(comm)));
78 Teuchos::RCP<Tpetra::Map<LO, GO, NT> > contigMap =
79 rcp(
new Tpetra::Map<LO, GO, NT>(invalid, gid.size(), 0, rcpFromRef(comm)));
81 return std::make_pair(gidMap, contigMap);
93 const ImExPair buildExportImport(
const Tpetra::Map<LO, GO, NT>& baseMap,
const MapPair& maps) {
94 return std::make_pair(rcp(
new Tpetra::Import<LO, GO, NT>(rcpFromRef(baseMap), maps.first)),
95 rcp(
new Tpetra::Export<LO, GO, NT>(maps.first, rcpFromRef(baseMap))));
105 void buildSubVectors(
const std::vector<MapPair>& maps,
106 std::vector<RCP<Tpetra::MultiVector<ST, LO, GO, NT> > >& vectors,
int count) {
107 std::vector<MapPair>::const_iterator mapItr;
110 for (mapItr = maps.begin(); mapItr != maps.end(); mapItr++) {
112 RCP<Tpetra::MultiVector<ST, LO, GO, NT> > mv =
113 rcp(
new Tpetra::MultiVector<ST, LO, GO, NT>((*mapItr).second, count));
114 vectors.push_back(mv);
125 void one2many(std::vector<RCP<Tpetra::MultiVector<ST, LO, GO, NT> > >& many,
126 const Tpetra::MultiVector<ST, LO, GO, NT>& single,
127 const std::vector<RCP<Tpetra::Import<LO, GO, NT> > >& subImport) {
129 std::vector<RCP<Tpetra::MultiVector<ST, LO, GO, NT> > >::const_iterator vecItr;
130 std::vector<RCP<Tpetra::Import<LO, GO, NT> > >::const_iterator impItr;
133 for (vecItr = many.begin(), impItr = subImport.begin(); vecItr != many.end();
134 ++vecItr, ++impItr) {
136 RCP<Tpetra::MultiVector<ST, LO, GO, NT> > destVec = *vecItr;
139 const Tpetra::Map<LO, GO, NT>& globalMap = *(*impItr)->getTargetMap();
142 GO lda = destVec->getStride();
143 GO destSize = destVec->getGlobalLength() * destVec->getNumVectors();
144 std::vector<ST> destArray(destSize);
145 Teuchos::ArrayView<ST> destVals(destArray);
146 destVec->get1dCopy(destVals, lda);
147 Tpetra::MultiVector<ST, LO, GO, NT> importVector(rcpFromRef(globalMap), destVals, lda,
148 destVec->getNumVectors());
151 importVector.doImport(single, **impItr, Tpetra::INSERT);
153 Tpetra::Import<LO, GO, NT> importer(destVec->getMap(), destVec->getMap());
154 importVector.replaceMap(destVec->getMap());
155 destVec->doExport(importVector, importer, Tpetra::INSERT);
169 void many2one(Tpetra::MultiVector<ST, LO, GO, NT>& one,
170 const std::vector<RCP<
const Tpetra::MultiVector<ST, LO, GO, NT> > >& many,
171 const std::vector<RCP<Tpetra::Export<LO, GO, NT> > >& subExport) {
173 std::vector<RCP<const Tpetra::MultiVector<ST, LO, GO, NT> > >::const_iterator vecItr;
174 std::vector<RCP<Tpetra::Export<LO, GO, NT> > >::const_iterator expItr;
177 for (vecItr = many.begin(), expItr = subExport.begin(); vecItr != many.end();
178 ++vecItr, ++expItr) {
180 RCP<const Tpetra::MultiVector<ST, LO, GO, NT> > srcVec = *vecItr;
183 const Tpetra::Map<LO, GO, NT>& globalMap = *(*expItr)->getSourceMap();
186 GO lda = srcVec->getStride();
187 GO srcSize = srcVec->getGlobalLength() * srcVec->getNumVectors();
188 std::vector<ST> srcArray(srcSize);
189 Teuchos::ArrayView<ST> srcVals(srcArray);
190 srcVec->get1dCopy(srcVals, lda);
191 Tpetra::MultiVector<ST, LO, GO, NT> exportVector(rcpFromRef(globalMap), srcVals, lda,
192 srcVec->getNumVectors());
195 one.doExport(exportVector, **expItr, Tpetra::INSERT);
204 RCP<Tpetra::Vector<GO, LO, GO, NT> > getSubBlockColumnGIDs(
205 const Tpetra::CrsMatrix<ST, LO, GO, NT>& A,
const MapPair& mapPair) {
206 RCP<const Tpetra::Map<LO, GO, NT> > blkGIDMap = mapPair.first;
207 RCP<const Tpetra::Map<LO, GO, NT> > blkContigMap = mapPair.second;
210 Tpetra::Vector<GO, LO, GO, NT> rIndex(A.getRowMap(),
true);
211 for (
size_t i = 0; i < A.getLocalNumRows(); i++) {
213 LO lid = blkGIDMap->getLocalElement(
214 A.getRowMap()->getGlobalElement(i));
216 rIndex.replaceLocalValue(i, blkContigMap->getGlobalElement(lid));
218 rIndex.replaceLocalValue(i, -1);
223 Tpetra::Import<LO, GO, NT>
import(A.getRowMap(), A.getColMap());
224 RCP<Tpetra::Vector<GO, LO, GO, NT> > cIndex =
225 rcp(
new Tpetra::Vector<GO, LO, GO, NT>(A.getColMap(),
true));
226 cIndex->doImport(rIndex,
import, Tpetra::INSERT);
232 RCP<Tpetra::CrsMatrix<ST, LO, GO, NT> > buildSubBlock(
233 int i,
int j,
const RCP<
const Tpetra::CrsMatrix<ST, LO, GO, NT> >& A,
234 const std::vector<MapPair>& subMaps) {
236 int numVarFamily = subMaps.size();
238 TEUCHOS_ASSERT(i >= 0 && i < numVarFamily);
239 TEUCHOS_ASSERT(j >= 0 && j < numVarFamily);
240 const RCP<const Tpetra::Map<LO, GO, NT> > gRowMap = subMaps[i].first;
241 const RCP<const Tpetra::Map<LO, GO, NT> > rowMap = subMaps[i].second;
242 const RCP<const Tpetra::Map<LO, GO, NT> > colMap = subMaps[j].second;
244 const RCP<Tpetra::Vector<GO, LO, GO, NT> > plocal2ContigGIDs =
245 getSubBlockColumnGIDs(*A, subMaps[j]);
246 Tpetra::Vector<GO, LO, GO, NT>& local2ContigGIDs = *plocal2ContigGIDs;
249 LO numMyRows = rowMap->getLocalNumElements();
250 LO maxNumEntries = A->getLocalMaxNumRowEntries();
253 auto indices =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_local_inds_host_view_type(
254 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
255 auto values =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_values_host_view_type(
256 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
259 std::vector<GO> colIndices(maxNumEntries);
260 std::vector<ST> colValues(maxNumEntries);
263 std::vector<size_t> nEntriesPerRow(numMyRows);
265 const size_t invalid = Teuchos::OrdinalTraits<size_t>::invalid();
269 for (LO localRow = 0; localRow < numMyRows; localRow++) {
270 size_t numEntries = invalid;
271 GO globalRow = gRowMap->getGlobalElement(localRow);
272 LO lid = A->getRowMap()->getLocalElement(globalRow);
273 TEUCHOS_ASSERT(lid > -1);
275 A->getLocalRowCopy(lid, indices, values, numEntries);
278 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
279 TEUCHOS_ASSERT(indices(localCol) > -1);
283 GO gid = local2ContigGIDs.getData()[indices[localCol]];
284 if (gid == -1)
continue;
287 nEntriesPerRow[localRow] = numOwnedCols;
290 RCP<Tpetra::CrsMatrix<ST, LO, GO, NT> > mat = rcp(
291 new Tpetra::CrsMatrix<ST, LO, GO, NT>(rowMap, Teuchos::ArrayView<size_t>(nEntriesPerRow)));
295 for (LO localRow = 0; localRow < numMyRows; localRow++) {
296 size_t numEntries = invalid;
297 GO globalRow = gRowMap->getGlobalElement(localRow);
298 LO lid = A->getRowMap()->getLocalElement(globalRow);
299 GO contigRow = rowMap->getGlobalElement(localRow);
300 TEUCHOS_ASSERT(lid > -1);
302 A->getLocalRowCopy(lid, indices, values, numEntries);
305 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
306 TEUCHOS_ASSERT(indices(localCol) > -1);
310 GO gid = local2ContigGIDs.getData()[indices(localCol)];
311 if (gid == -1)
continue;
313 colIndices[numOwnedCols] = gid;
314 colValues[numOwnedCols] = values(localCol);
319 colIndices.resize(numOwnedCols);
320 colValues.resize(numOwnedCols);
321 mat->insertGlobalValues(contigRow, Teuchos::ArrayView<GO>(colIndices),
322 Teuchos::ArrayView<ST>(colValues));
323 colIndices.resize(maxNumEntries);
324 colValues.resize(maxNumEntries);
328 mat->fillComplete(colMap, rowMap);
334 void rebuildSubBlock(
int i,
int j,
const RCP<
const Tpetra::CrsMatrix<ST, LO, GO, NT> >& A,
335 const std::vector<MapPair>& subMaps, Tpetra::CrsMatrix<ST, LO, GO, NT>& mat) {
337 int numVarFamily = subMaps.size();
339 TEUCHOS_ASSERT(i >= 0 && i < numVarFamily);
340 TEUCHOS_ASSERT(j >= 0 && j < numVarFamily);
342 const Tpetra::Map<LO, GO, NT>& gRowMap = *subMaps[i].first;
343 const Tpetra::Map<LO, GO, NT>& rowMap = *subMaps[i].second;
344 const Tpetra::Map<LO, GO, NT>& colMap = *subMaps[j].second;
346 const RCP<Tpetra::Vector<GO, LO, GO, NT> > plocal2ContigGIDs =
347 getSubBlockColumnGIDs(*A, subMaps[j]);
348 Tpetra::Vector<GO, LO, GO, NT>& local2ContigGIDs = *plocal2ContigGIDs;
351 mat.setAllToScalar(0.0);
354 LO numMyRows = rowMap.getLocalNumElements();
355 LO maxNumEntries = A->getLocalMaxNumRowEntries();
358 auto indices =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_local_inds_host_view_type(
359 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
360 auto values =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_values_host_view_type(
361 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
364 std::vector<GO> colIndices(maxNumEntries);
365 std::vector<ST> colValues(maxNumEntries);
367 const size_t invalid = Teuchos::OrdinalTraits<size_t>::invalid();
371 for (LO localRow = 0; localRow < numMyRows; localRow++) {
372 size_t numEntries = invalid;
373 GO globalRow = gRowMap.getGlobalElement(localRow);
374 LO lid = A->getRowMap()->getLocalElement(globalRow);
375 GO contigRow = rowMap.getGlobalElement(localRow);
376 TEUCHOS_ASSERT(lid > -1);
378 A->getLocalRowCopy(lid, indices, values, numEntries);
381 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
382 TEUCHOS_ASSERT(indices(localCol) > -1);
385 GO gid = local2ContigGIDs.getData()[indices(localCol)];
386 if (gid == -1)
continue;
388 colIndices[numOwnedCols] = gid;
389 colValues[numOwnedCols] = values(localCol);
394 colIndices.resize(numOwnedCols);
395 colValues.resize(numOwnedCols);
396 mat.sumIntoGlobalValues(contigRow, Teuchos::ArrayView<GO>(colIndices),
397 Teuchos::ArrayView<ST>(colValues));
398 colIndices.resize(maxNumEntries);
399 colValues.resize(maxNumEntries);
401 mat.fillComplete(rcpFromRef(colMap), rcpFromRef(rowMap));