10#include "Teko_BlockingTpetra.hpp"
13#include "Tpetra_Vector.hpp"
14#include "Tpetra_Map.hpp"
20namespace TpetraHelpers {
36const MapPair buildSubMap(
const std::vector<GO>& gid,
const Teuchos::Comm<int>& comm) {
37 using GST = Tpetra::global_size_t;
38 const GST invalid = Teuchos::OrdinalTraits<GST>::invalid();
39 Teuchos::RCP<Tpetra::Map<LO, GO, NT> > gidMap = rcp(
40 new Tpetra::Map<LO, GO, NT>(invalid, Teuchos::ArrayView<const GO>(gid), 0, rcpFromRef(comm)));
41 Teuchos::RCP<Tpetra::Map<LO, GO, NT> > contigMap =
42 rcp(
new Tpetra::Map<LO, GO, NT>(invalid, gid.size(), 0, rcpFromRef(comm)));
44 return std::make_pair(gidMap, contigMap);
56const ImExPair buildExportImport(
const Tpetra::Map<LO, GO, NT>& baseMap,
const MapPair& maps) {
57 return std::make_pair(rcp(
new Tpetra::Import<LO, GO, NT>(rcpFromRef(baseMap), maps.first)),
58 rcp(
new Tpetra::Export<LO, GO, NT>(maps.first, rcpFromRef(baseMap))));
68void buildSubVectors(
const std::vector<MapPair>& maps,
69 std::vector<RCP<Tpetra::MultiVector<ST, LO, GO, NT> > >& vectors,
int count) {
70 std::vector<MapPair>::const_iterator mapItr;
73 for (mapItr = maps.begin(); mapItr != maps.end(); mapItr++) {
75 RCP<Tpetra::MultiVector<ST, LO, GO, NT> > mv =
76 rcp(
new Tpetra::MultiVector<ST, LO, GO, NT>((*mapItr).second, count));
77 vectors.push_back(mv);
88void one2many(std::vector<RCP<Tpetra::MultiVector<ST, LO, GO, NT> > >& many,
89 const Tpetra::MultiVector<ST, LO, GO, NT>& single,
90 const std::vector<RCP<Tpetra::Import<LO, GO, NT> > >& subImport) {
92 std::vector<RCP<Tpetra::MultiVector<ST, LO, GO, NT> > >::const_iterator vecItr;
93 std::vector<RCP<Tpetra::Import<LO, GO, NT> > >::const_iterator impItr;
96 for (vecItr = many.begin(), impItr = subImport.begin(); vecItr != many.end();
99 RCP<Tpetra::MultiVector<ST, LO, GO, NT> > destVec = *vecItr;
102 const Tpetra::Map<LO, GO, NT>& globalMap = *(*impItr)->getTargetMap();
105 GO lda = destVec->getStride();
106 GO destSize = destVec->getGlobalLength() * destVec->getNumVectors();
107 std::vector<ST> destArray(destSize);
108 Teuchos::ArrayView<ST> destVals(destArray);
109 destVec->get1dCopy(destVals, lda);
110 Tpetra::MultiVector<ST, LO, GO, NT> importVector(rcpFromRef(globalMap), destVals, lda,
111 destVec->getNumVectors());
114 importVector.doImport(single, **impItr, Tpetra::INSERT);
116 Tpetra::Import<LO, GO, NT> importer(destVec->getMap(), destVec->getMap());
117 importVector.replaceMap(destVec->getMap());
118 destVec->doExport(importVector, importer, Tpetra::INSERT);
132void many2one(Tpetra::MultiVector<ST, LO, GO, NT>& one,
133 const std::vector<RCP<
const Tpetra::MultiVector<ST, LO, GO, NT> > >& many,
134 const std::vector<RCP<Tpetra::Export<LO, GO, NT> > >& subExport) {
136 std::vector<RCP<const Tpetra::MultiVector<ST, LO, GO, NT> > >::const_iterator vecItr;
137 std::vector<RCP<Tpetra::Export<LO, GO, NT> > >::const_iterator expItr;
140 for (vecItr = many.begin(), expItr = subExport.begin(); vecItr != many.end();
141 ++vecItr, ++expItr) {
143 RCP<const Tpetra::MultiVector<ST, LO, GO, NT> > srcVec = *vecItr;
146 const Tpetra::Map<LO, GO, NT>& globalMap = *(*expItr)->getSourceMap();
149 GO lda = srcVec->getStride();
150 GO srcSize = srcVec->getGlobalLength() * srcVec->getNumVectors();
151 std::vector<ST> srcArray(srcSize);
152 Teuchos::ArrayView<ST> srcVals(srcArray);
153 srcVec->get1dCopy(srcVals, lda);
154 Tpetra::MultiVector<ST, LO, GO, NT> exportVector(rcpFromRef(globalMap), srcVals, lda,
155 srcVec->getNumVectors());
158 one.doExport(exportVector, **expItr, Tpetra::INSERT);
167RCP<Tpetra::Vector<GO, LO, GO, NT> > getSubBlockColumnGIDs(
168 const Tpetra::CrsMatrix<ST, LO, GO, NT>& A,
const MapPair& mapPair) {
169 RCP<const Tpetra::Map<LO, GO, NT> > blkGIDMap = mapPair.first;
170 RCP<const Tpetra::Map<LO, GO, NT> > blkContigMap = mapPair.second;
173 Tpetra::Vector<GO, LO, GO, NT> rIndex(A.getRowMap(),
true);
174 for (
size_t i = 0; i < A.getLocalNumRows(); i++) {
176 LO lid = blkGIDMap->getLocalElement(
177 A.getRowMap()->getGlobalElement(i));
179 rIndex.replaceLocalValue(i, blkContigMap->getGlobalElement(lid));
181 rIndex.replaceLocalValue(i, -1);
186 Tpetra::Import<LO, GO, NT>
import(A.getRowMap(), A.getColMap());
187 RCP<Tpetra::Vector<GO, LO, GO, NT> > cIndex =
188 rcp(
new Tpetra::Vector<GO, LO, GO, NT>(A.getColMap(),
true));
189 cIndex->doImport(rIndex,
import, Tpetra::INSERT);
195RCP<Tpetra::CrsMatrix<ST, LO, GO, NT> > buildSubBlock(
196 int i,
int j,
const RCP<
const Tpetra::CrsMatrix<ST, LO, GO, NT> >& A,
197 const std::vector<MapPair>& subMaps,
198 Teuchos::RCP<Tpetra::Vector<GO, LO, GO, NT> > plocal2ContigGIDs) {
200 int numVarFamily = subMaps.size();
202 TEUCHOS_ASSERT(i >= 0 && i < numVarFamily);
203 TEUCHOS_ASSERT(j >= 0 && j < numVarFamily);
204 const RCP<const Tpetra::Map<LO, GO, NT> > gRowMap = subMaps[i].first;
205 const RCP<const Tpetra::Map<LO, GO, NT> > rowMap = subMaps[i].second;
206 const RCP<const Tpetra::Map<LO, GO, NT> > colMap = subMaps[j].second;
208 if (!plocal2ContigGIDs) {
209 plocal2ContigGIDs = Blocking::getSubBlockColumnGIDs(*A, subMaps[j]);
211 Tpetra::Vector<GO, LO, GO, NT>& local2ContigGIDs = *plocal2ContigGIDs;
214 LO numMyRows = rowMap->getLocalNumElements();
215 LO maxNumEntries = A->getLocalMaxNumRowEntries();
218 auto indices =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_local_inds_host_view_type(
219 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
220 auto values =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_values_host_view_type(
221 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
224 std::vector<GO> colIndices(maxNumEntries);
225 std::vector<ST> colValues(maxNumEntries);
228 std::vector<size_t> nEntriesPerRow(numMyRows);
230 const size_t invalid = Teuchos::OrdinalTraits<size_t>::invalid();
234 for (LO localRow = 0; localRow < numMyRows; localRow++) {
235 size_t numEntries = invalid;
236 GO globalRow = gRowMap->getGlobalElement(localRow);
237 LO lid = A->getRowMap()->getLocalElement(globalRow);
238 TEUCHOS_ASSERT(lid > -1);
240 A->getLocalRowCopy(lid, indices, values, numEntries);
243 auto data = local2ContigGIDs.getLocalViewHost(Tpetra::Access::ReadOnly);
244 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
245 TEUCHOS_ASSERT(indices(localCol) > -1);
249 GO gid = data(indices[localCol], 0);
250 if (gid == -1)
continue;
253 nEntriesPerRow[localRow] = numOwnedCols;
256 RCP<Tpetra::CrsMatrix<ST, LO, GO, NT> > mat = rcp(
257 new Tpetra::CrsMatrix<ST, LO, GO, NT>(rowMap, Teuchos::ArrayView<size_t>(nEntriesPerRow)));
261 for (LO localRow = 0; localRow < numMyRows; localRow++) {
262 size_t numEntries = invalid;
263 GO globalRow = gRowMap->getGlobalElement(localRow);
264 LO lid = A->getRowMap()->getLocalElement(globalRow);
265 GO contigRow = rowMap->getGlobalElement(localRow);
266 TEUCHOS_ASSERT(lid > -1);
268 A->getLocalRowCopy(lid, indices, values, numEntries);
271 auto data = local2ContigGIDs.getLocalViewHost(Tpetra::Access::ReadOnly);
272 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
273 TEUCHOS_ASSERT(indices(localCol) > -1);
277 GO gid = data(indices(localCol), 0);
278 if (gid == -1)
continue;
280 colIndices[numOwnedCols] = gid;
281 colValues[numOwnedCols] = values(localCol);
286 mat->insertGlobalValues(contigRow, Teuchos::ArrayView<GO>(colIndices.data(), numOwnedCols),
287 Teuchos::ArrayView<ST>(colValues.data(), numOwnedCols));
291 mat->fillComplete(colMap, rowMap);
297void rebuildSubBlock(
int i,
int j,
const RCP<
const Tpetra::CrsMatrix<ST, LO, GO, NT> >& A,
298 const std::vector<MapPair>& subMaps, Tpetra::CrsMatrix<ST, LO, GO, NT>& mat,
299 Teuchos::RCP<Tpetra::Vector<GO, LO, GO, NT> > plocal2ContigGIDs) {
301 int numVarFamily = subMaps.size();
303 TEUCHOS_ASSERT(i >= 0 && i < numVarFamily);
304 TEUCHOS_ASSERT(j >= 0 && j < numVarFamily);
306 const Tpetra::Map<LO, GO, NT>& gRowMap = *subMaps[i].first;
307 const Tpetra::Map<LO, GO, NT>& rowMap = *subMaps[i].second;
308 const Tpetra::Map<LO, GO, NT>& colMap = *subMaps[j].second;
310 if (!plocal2ContigGIDs) {
311 plocal2ContigGIDs = Blocking::getSubBlockColumnGIDs(*A, subMaps[j]);
313 Tpetra::Vector<GO, LO, GO, NT>& local2ContigGIDs = *plocal2ContigGIDs;
316 mat.setAllToScalar(0.0);
319 LO numMyRows = rowMap.getLocalNumElements();
320 LO maxNumEntries = A->getLocalMaxNumRowEntries();
323 auto indices =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_local_inds_host_view_type(
324 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
325 auto values =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_values_host_view_type(
326 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
329 std::vector<GO> colIndices(maxNumEntries);
330 std::vector<ST> colValues(maxNumEntries);
332 const size_t invalid = Teuchos::OrdinalTraits<size_t>::invalid();
336 auto A_rowmap = A->getRowMap();
337 for (LO localRow = 0; localRow < numMyRows; localRow++) {
338 size_t numEntries = invalid;
339 GO globalRow = gRowMap.getGlobalElement(localRow);
340 LO lid = A_rowmap->getLocalElement(globalRow);
341 GO contigRow = rowMap.getGlobalElement(localRow);
342 TEUCHOS_ASSERT(lid > -1);
344 A->getLocalRowCopy(lid, indices, values, numEntries);
347 auto data = local2ContigGIDs.getLocalViewHost(Tpetra::Access::ReadOnly);
348 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
349 TEUCHOS_ASSERT(indices(localCol) > -1);
352 GO gid = data(indices(localCol), 0);
353 if (gid == -1)
continue;
355 colIndices[numOwnedCols] = gid;
356 colValues[numOwnedCols] = values(localCol);
360 mat.sumIntoGlobalValues(contigRow, Teuchos::ArrayView<GO>(colIndices.data(), numOwnedCols),
361 Teuchos::ArrayView<ST>(colValues.data(), numOwnedCols));
364 mat.fillComplete(rcpFromRef(colMap), rcpFromRef(rowMap));