10 #include "Teko_BlockingTpetra.hpp"
13 #include "Tpetra_Vector.hpp"
14 #include "Tpetra_Map.hpp"
20 namespace TpetraHelpers {
36 const 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);
56 const 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))));
68 void 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);
88 void 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);
132 void 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);
167 RCP<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);
195 RCP<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) {
199 int numVarFamily = subMaps.size();
201 TEUCHOS_ASSERT(i >= 0 && i < numVarFamily);
202 TEUCHOS_ASSERT(j >= 0 && j < numVarFamily);
203 const RCP<const Tpetra::Map<LO, GO, NT> > gRowMap = subMaps[i].first;
204 const RCP<const Tpetra::Map<LO, GO, NT> > rowMap = subMaps[i].second;
205 const RCP<const Tpetra::Map<LO, GO, NT> > colMap = subMaps[j].second;
207 const RCP<Tpetra::Vector<GO, LO, GO, NT> > plocal2ContigGIDs =
208 getSubBlockColumnGIDs(*A, subMaps[j]);
209 Tpetra::Vector<GO, LO, GO, NT>& local2ContigGIDs = *plocal2ContigGIDs;
212 LO numMyRows = rowMap->getLocalNumElements();
213 LO maxNumEntries = A->getLocalMaxNumRowEntries();
216 auto indices =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_local_inds_host_view_type(
217 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
218 auto values =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_values_host_view_type(
219 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
222 std::vector<GO> colIndices(maxNumEntries);
223 std::vector<ST> colValues(maxNumEntries);
226 std::vector<size_t> nEntriesPerRow(numMyRows);
228 const size_t invalid = Teuchos::OrdinalTraits<size_t>::invalid();
232 for (LO localRow = 0; localRow < numMyRows; localRow++) {
233 size_t numEntries = invalid;
234 GO globalRow = gRowMap->getGlobalElement(localRow);
235 LO lid = A->getRowMap()->getLocalElement(globalRow);
236 TEUCHOS_ASSERT(lid > -1);
238 A->getLocalRowCopy(lid, indices, values, numEntries);
241 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
242 TEUCHOS_ASSERT(indices(localCol) > -1);
246 GO gid = local2ContigGIDs.getData()[indices[localCol]];
247 if (gid == -1)
continue;
250 nEntriesPerRow[localRow] = numOwnedCols;
253 RCP<Tpetra::CrsMatrix<ST, LO, GO, NT> > mat = rcp(
254 new Tpetra::CrsMatrix<ST, LO, GO, NT>(rowMap, Teuchos::ArrayView<size_t>(nEntriesPerRow)));
258 for (LO localRow = 0; localRow < numMyRows; localRow++) {
259 size_t numEntries = invalid;
260 GO globalRow = gRowMap->getGlobalElement(localRow);
261 LO lid = A->getRowMap()->getLocalElement(globalRow);
262 GO contigRow = rowMap->getGlobalElement(localRow);
263 TEUCHOS_ASSERT(lid > -1);
265 A->getLocalRowCopy(lid, indices, values, numEntries);
268 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
269 TEUCHOS_ASSERT(indices(localCol) > -1);
273 GO gid = local2ContigGIDs.getData()[indices(localCol)];
274 if (gid == -1)
continue;
276 colIndices[numOwnedCols] = gid;
277 colValues[numOwnedCols] = values(localCol);
282 colIndices.resize(numOwnedCols);
283 colValues.resize(numOwnedCols);
284 mat->insertGlobalValues(contigRow, Teuchos::ArrayView<GO>(colIndices),
285 Teuchos::ArrayView<ST>(colValues));
286 colIndices.resize(maxNumEntries);
287 colValues.resize(maxNumEntries);
291 mat->fillComplete(colMap, rowMap);
297 void 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) {
300 int numVarFamily = subMaps.size();
302 TEUCHOS_ASSERT(i >= 0 && i < numVarFamily);
303 TEUCHOS_ASSERT(j >= 0 && j < numVarFamily);
305 const Tpetra::Map<LO, GO, NT>& gRowMap = *subMaps[i].first;
306 const Tpetra::Map<LO, GO, NT>& rowMap = *subMaps[i].second;
307 const Tpetra::Map<LO, GO, NT>& colMap = *subMaps[j].second;
309 const RCP<Tpetra::Vector<GO, LO, GO, NT> > plocal2ContigGIDs =
310 getSubBlockColumnGIDs(*A, subMaps[j]);
311 Tpetra::Vector<GO, LO, GO, NT>& local2ContigGIDs = *plocal2ContigGIDs;
314 mat.setAllToScalar(0.0);
317 LO numMyRows = rowMap.getLocalNumElements();
318 LO maxNumEntries = A->getLocalMaxNumRowEntries();
321 auto indices =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_local_inds_host_view_type(
322 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
323 auto values =
typename Tpetra::CrsMatrix<ST, LO, GO, NT>::nonconst_values_host_view_type(
324 Kokkos::ViewAllocateWithoutInitializing(
"rowIndices"), maxNumEntries);
327 std::vector<GO> colIndices(maxNumEntries);
328 std::vector<ST> colValues(maxNumEntries);
330 const size_t invalid = Teuchos::OrdinalTraits<size_t>::invalid();
334 for (LO localRow = 0; localRow < numMyRows; localRow++) {
335 size_t numEntries = invalid;
336 GO globalRow = gRowMap.getGlobalElement(localRow);
337 LO lid = A->getRowMap()->getLocalElement(globalRow);
338 GO contigRow = rowMap.getGlobalElement(localRow);
339 TEUCHOS_ASSERT(lid > -1);
341 A->getLocalRowCopy(lid, indices, values, numEntries);
344 for (
size_t localCol = 0; localCol < numEntries; localCol++) {
345 TEUCHOS_ASSERT(indices(localCol) > -1);
348 GO gid = local2ContigGIDs.getData()[indices(localCol)];
349 if (gid == -1)
continue;
351 colIndices[numOwnedCols] = gid;
352 colValues[numOwnedCols] = values(localCol);
357 colIndices.resize(numOwnedCols);
358 colValues.resize(numOwnedCols);
359 mat.sumIntoGlobalValues(contigRow, Teuchos::ArrayView<GO>(colIndices),
360 Teuchos::ArrayView<ST>(colValues));
361 colIndices.resize(maxNumEntries);
362 colValues.resize(maxNumEntries);
364 mat.fillComplete(rcpFromRef(colMap), rcpFromRef(rowMap));