47 #include "Teko_InterlacedEpetra.hpp"
61 void buildSubMaps(
int numGlobals,
int numVars,
const Epetra_Comm& comm,
62 std::vector<std::pair<
int, RCP<Epetra_Map> > >& subMaps) {
63 std::vector<int> vars;
66 for (
int i = 0; i < numVars; i++) vars.push_back(1);
69 buildSubMaps(numGlobals, vars, comm, subMaps);
73 void buildSubMaps(
const Epetra_Map& globalMap,
const std::vector<int>& vars,
74 const Epetra_Comm& comm,
75 std::vector<std::pair<
int, Teuchos::RCP<Epetra_Map> > >& subMaps) {
76 buildSubMaps(globalMap.NumGlobalElements(), globalMap.NumMyElements(), globalMap.MinMyGID(), vars,
81 void buildSubMaps(
int numGlobals,
const std::vector<int>& vars,
const Epetra_Comm& comm,
82 std::vector<std::pair<
int, Teuchos::RCP<Epetra_Map> > >& subMaps) {
83 std::vector<int>::const_iterator varItr;
86 int numGlobalVars = 0;
87 for (varItr = vars.begin(); varItr != vars.end(); ++varItr) numGlobalVars += *varItr;
90 TEUCHOS_ASSERT((numGlobals % numGlobalVars) == 0);
92 Epetra_Map sampleMap(numGlobals / numGlobalVars, 0, comm);
94 buildSubMaps(numGlobals, numGlobalVars * sampleMap.NumMyElements(),
95 numGlobalVars * sampleMap.MinMyGID(), vars, comm, subMaps);
99 void buildSubMaps(
int numGlobals,
int numMyElements,
int minMyGID,
const std::vector<int>& vars,
100 const Epetra_Comm& comm,
101 std::vector<std::pair<
int, Teuchos::RCP<Epetra_Map> > >& subMaps) {
102 std::vector<int>::const_iterator varItr;
105 int numGlobalVars = 0;
106 for (varItr = vars.begin(); varItr != vars.end(); ++varItr) numGlobalVars += *varItr;
109 TEUCHOS_ASSERT((numGlobals % numGlobalVars) == 0);
110 TEUCHOS_ASSERT((numMyElements % numGlobalVars) == 0);
111 TEUCHOS_ASSERT((minMyGID % numGlobalVars) == 0);
113 int numBlocks = numMyElements / numGlobalVars;
114 int minBlockID = minMyGID / numGlobalVars;
120 for (varItr = vars.begin(); varItr != vars.end(); ++varItr) {
121 int numLocalVars = *varItr;
122 int numAllElmts = numLocalVars * numGlobals / numGlobalVars;
123 int numMyElmts = numLocalVars * numBlocks;
126 std::vector<int> subGlobals;
127 std::vector<int> contigGlobals;
131 for (
int blockNum = 0; blockNum < numBlocks; blockNum++) {
133 for (
int local = 0; local < numLocalVars; ++local) {
137 subGlobals.push_back((minBlockID + blockNum) * numGlobalVars + blockOffset + local);
140 contigGlobals.push_back(numLocalVars * minBlockID + count);
146 assert((
unsigned int)numMyElmts == subGlobals.size());
149 RCP<Epetra_Map> subMap = rcp(
new Epetra_Map(numAllElmts, numMyElmts, &subGlobals[0], 0, comm));
150 RCP<Epetra_Map> contigMap =
151 rcp(
new Epetra_Map(numAllElmts, numMyElmts, &contigGlobals[0], 0, comm));
153 Teuchos::set_extra_data(contigMap,
"contigMap", Teuchos::inOutArg(subMap));
154 subMaps.push_back(std::make_pair(numLocalVars, subMap));
157 blockOffset += numLocalVars;
161 void buildExportImport(
const Epetra_Map& baseMap,
162 const std::vector<std::pair<
int, RCP<Epetra_Map> > >& subMaps,
163 std::vector<RCP<Epetra_Export> >& subExport,
164 std::vector<RCP<Epetra_Import> >& subImport) {
165 std::vector<std::pair<int, RCP<Epetra_Map> > >::const_iterator mapItr;
168 for (mapItr = subMaps.begin(); mapItr != subMaps.end(); ++mapItr) {
170 const Epetra_Map& map = *(mapItr->second);
173 subImport.push_back(rcp(
new Epetra_Import(map, baseMap)));
174 subExport.push_back(rcp(
new Epetra_Export(map, baseMap)));
178 void buildSubVectors(
const std::vector<std::pair<
int, RCP<Epetra_Map> > >& subMaps,
179 std::vector<RCP<Epetra_MultiVector> >& subVectors,
int count) {
180 std::vector<std::pair<int, RCP<Epetra_Map> > >::const_iterator mapItr;
183 for (mapItr = subMaps.begin(); mapItr != subMaps.end(); ++mapItr) {
185 const Epetra_Map& map =
186 *(Teuchos::get_extra_data<RCP<Epetra_Map> >(mapItr->second,
"contigMap"));
189 RCP<Epetra_MultiVector> mv = rcp(
new Epetra_MultiVector(map, count));
190 Teuchos::set_extra_data(mapItr->second,
"globalMap", Teuchos::inOutArg(mv));
191 subVectors.push_back(mv);
195 void associateSubVectors(
const std::vector<std::pair<
int, RCP<Epetra_Map> > >& subMaps,
196 std::vector<RCP<const Epetra_MultiVector> >& subVectors) {
197 std::vector<std::pair<int, RCP<Epetra_Map> > >::const_iterator mapItr;
198 std::vector<RCP<const Epetra_MultiVector> >::iterator vecItr;
200 TEUCHOS_ASSERT(subMaps.size() == subVectors.size());
203 for (mapItr = subMaps.begin(), vecItr = subVectors.begin(); mapItr != subMaps.end();
205 Teuchos::set_extra_data(mapItr->second,
"globalMap", Teuchos::inOutArg(*vecItr));
209 RCP<Epetra_CrsMatrix> buildSubBlock(
int i,
int j,
const Epetra_CrsMatrix& A,
210 const std::vector<std::pair<
int, RCP<Epetra_Map> > >& subMaps) {
212 int numVarFamily = subMaps.size();
214 TEUCHOS_ASSERT(i >= 0 && i < numVarFamily);
215 TEUCHOS_ASSERT(j >= 0 && j < numVarFamily);
217 const Epetra_Map& gRowMap = *subMaps[i].second;
218 const Epetra_Map& rowMap =
219 *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[i].second,
"contigMap");
220 const Epetra_Map& colMap =
221 *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[j].second,
"contigMap");
222 int colFamilyCnt = subMaps[j].first;
226 int numGlobalVars = 0;
227 int rowBlockOffset = 0;
228 int colBlockOffset = 0;
229 for (
int k = 0; k < numVarFamily; k++) {
230 numGlobalVars += subMaps[k].first;
233 if (k < i) rowBlockOffset += subMaps[k].first;
234 if (k < j) colBlockOffset += subMaps[k].first;
238 Epetra_Import
import(gRowMap, A.RowMap());
239 Epetra_CrsMatrix localA(Copy, gRowMap, 0);
240 localA.Import(A,
import, Insert);
242 RCP<Epetra_CrsMatrix> mat = rcp(
new Epetra_CrsMatrix(Copy, rowMap, 0));
245 int numMyRows = rowMap.NumMyElements();
246 int maxNumEntries = A.GlobalMaxNumEntries();
249 std::vector<int> indices(maxNumEntries);
250 std::vector<double> values(maxNumEntries);
253 std::vector<int> colIndices(maxNumEntries);
254 std::vector<double> colValues(maxNumEntries);
258 for (
int localRow = 0; localRow < numMyRows; localRow++) {
260 int globalRow = gRowMap.GID(localRow);
261 int contigRow = rowMap.GID(localRow);
263 TEUCHOS_ASSERT(globalRow >= 0);
264 TEUCHOS_ASSERT(contigRow >= 0);
268 localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]);
269 TEUCHOS_ASSERT(err == 0);
271 int numOwnedCols = 0;
272 for (
int localCol = 0; localCol < numEntries; localCol++) {
273 int globalCol = indices[localCol];
276 int block = globalCol / numGlobalVars;
278 bool inFamily =
true;
281 inFamily &= (block * numGlobalVars + colBlockOffset <= globalCol);
282 inFamily &= ((block * numGlobalVars + colBlockOffset + colFamilyCnt) > globalCol);
286 int familyOffset = globalCol - (block * numGlobalVars + colBlockOffset);
288 colIndices[numOwnedCols] = block * colFamilyCnt + familyOffset;
289 colValues[numOwnedCols] = values[localCol];
296 mat->InsertGlobalValues(contigRow, numOwnedCols, &colValues[0], &colIndices[0]);
300 mat->FillComplete(colMap, rowMap);
306 void rebuildSubBlock(
int i,
int j,
const Epetra_CrsMatrix& A,
307 const std::vector<std::pair<
int, RCP<Epetra_Map> > >& subMaps,
308 Epetra_CrsMatrix& mat) {
310 int numVarFamily = subMaps.size();
312 TEUCHOS_ASSERT(i >= 0 && i < numVarFamily);
313 TEUCHOS_ASSERT(j >= 0 && j < numVarFamily);
314 TEUCHOS_ASSERT(mat.Filled());
316 const Epetra_Map& gRowMap = *subMaps[i].second;
317 const Epetra_Map& rowMap =
318 *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[i].second,
"contigMap");
319 int colFamilyCnt = subMaps[j].first;
323 int numGlobalVars = 0;
324 int rowBlockOffset = 0;
325 int colBlockOffset = 0;
326 for (
int k = 0; k < numVarFamily; k++) {
327 numGlobalVars += subMaps[k].first;
330 if (k < i) rowBlockOffset += subMaps[k].first;
331 if (k < j) colBlockOffset += subMaps[k].first;
335 Epetra_Import
import(gRowMap, A.RowMap());
336 Epetra_CrsMatrix localA(Copy, gRowMap, 0);
337 localA.Import(A,
import, Insert);
343 int numMyRows = rowMap.NumMyElements();
344 int maxNumEntries = A.GlobalMaxNumEntries();
347 std::vector<int> indices(maxNumEntries);
348 std::vector<double> values(maxNumEntries);
351 std::vector<int> colIndices(maxNumEntries);
352 std::vector<double> colValues(maxNumEntries);
356 for (
int localRow = 0; localRow < numMyRows; localRow++) {
358 int globalRow = gRowMap.GID(localRow);
359 int contigRow = rowMap.GID(localRow);
361 TEUCHOS_ASSERT(globalRow >= 0);
362 TEUCHOS_ASSERT(contigRow >= 0);
366 localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]);
367 TEUCHOS_ASSERT(err == 0);
369 int numOwnedCols = 0;
370 for (
int localCol = 0; localCol < numEntries; localCol++) {
371 int globalCol = indices[localCol];
374 int block = globalCol / numGlobalVars;
376 bool inFamily =
true;
379 inFamily &= (block * numGlobalVars + colBlockOffset <= globalCol);
380 inFamily &= ((block * numGlobalVars + colBlockOffset + colFamilyCnt) > globalCol);
384 int familyOffset = globalCol - (block * numGlobalVars + colBlockOffset);
386 colIndices[numOwnedCols] = block * colFamilyCnt + familyOffset;
387 colValues[numOwnedCols] = values[localCol];
394 mat.SumIntoGlobalValues(contigRow, numOwnedCols, &colValues[0], &colIndices[0]);
399 void many2one(Epetra_MultiVector& one,
const std::vector<RCP<const Epetra_MultiVector> >& many,
400 const std::vector<RCP<Epetra_Export> >& subExport) {
402 std::vector<RCP<const Epetra_MultiVector> >::const_iterator vecItr;
403 std::vector<RCP<Epetra_Export> >::const_iterator expItr;
406 for (vecItr = many.begin(), expItr = subExport.begin(); vecItr != many.end();
407 ++vecItr, ++expItr) {
409 RCP<const Epetra_MultiVector> srcVec = *vecItr;
412 const Epetra_Map& globalMap = *(Teuchos::get_extra_data<RCP<Epetra_Map> >(srcVec,
"globalMap"));
415 Epetra_MultiVector exportVector(View, globalMap, srcVec->Values(), srcVec->Stride(),
416 srcVec->NumVectors());
417 one.Export(exportVector, **expItr, Insert);
422 void one2many(std::vector<RCP<Epetra_MultiVector> >& many,
const Epetra_MultiVector& single,
423 const std::vector<RCP<Epetra_Import> >& subImport) {
425 std::vector<RCP<Epetra_MultiVector> >::const_iterator vecItr;
426 std::vector<RCP<Epetra_Import> >::const_iterator impItr;
429 for (vecItr = many.begin(), impItr = subImport.begin(); vecItr != many.end();
430 ++vecItr, ++impItr) {
432 RCP<Epetra_MultiVector> destVec = *vecItr;
435 const Epetra_Map& globalMap =
436 *(Teuchos::get_extra_data<RCP<Epetra_Map> >(destVec,
"globalMap"));
439 Epetra_MultiVector importVector(View, globalMap, destVec->Values(), destVec->Stride(),
440 destVec->NumVectors());
443 importVector.Import(single, **impItr, Insert);