47 #include "Teko_InterlacedEpetra.hpp"
61 void buildSubMaps(
int numGlobals,
int numVars,
const Epetra_Comm & comm,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,
const Epetra_Comm & comm,
74 std::vector<std::pair<
int,Teuchos::RCP<Epetra_Map> > > & subMaps)
76 buildSubMaps(globalMap.NumGlobalElements(),globalMap.NumMyElements(),globalMap.MinMyGID(),
81 void buildSubMaps(
int numGlobals,
const std::vector<int> & vars,
const Epetra_Comm & comm,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)
88 numGlobalVars += *varItr;
91 TEUCHOS_ASSERT((numGlobals%numGlobalVars)==0);
93 Epetra_Map sampleMap(numGlobals/numGlobalVars,0,comm);
95 buildSubMaps(numGlobals,numGlobalVars*sampleMap.NumMyElements(),numGlobalVars*sampleMap.MinMyGID(),vars,comm,subMaps);
99 void buildSubMaps(
int numGlobals,
int numMyElements,
int minMyGID,
const std::vector<int> & vars,
const Epetra_Comm & comm,
100 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)
107 numGlobalVars += *varItr;
110 TEUCHOS_ASSERT((numGlobals%numGlobalVars)==0);
111 TEUCHOS_ASSERT((numMyElements%numGlobalVars)==0);
112 TEUCHOS_ASSERT((minMyGID%numGlobalVars)==0);
114 int numBlocks = numMyElements/numGlobalVars;
115 int minBlockID = minMyGID/numGlobalVars;
121 for(varItr=vars.begin();varItr!=vars.end();++varItr) {
122 int numLocalVars = *varItr;
123 int numAllElmts = numLocalVars*numGlobals/numGlobalVars;
124 int numMyElmts = numLocalVars * numBlocks;
127 std::vector<int> subGlobals;
128 std::vector<int> contigGlobals;
132 for(
int blockNum=0;blockNum<numBlocks;blockNum++) {
135 for(
int local=0;local<numLocalVars;++local) {
139 subGlobals.push_back((minBlockID+blockNum)*numGlobalVars+blockOffset+local);
142 contigGlobals.push_back(numLocalVars*minBlockID+count);
148 assert((
unsigned int) numMyElmts==subGlobals.size());
151 RCP<Epetra_Map> subMap = rcp(
new Epetra_Map(numAllElmts,numMyElmts,&subGlobals[0],0,comm));
152 RCP<Epetra_Map> contigMap = rcp(
new Epetra_Map(numAllElmts,numMyElmts,&contigGlobals[0],0,comm));
154 Teuchos::set_extra_data(contigMap,
"contigMap",Teuchos::inOutArg(subMap));
155 subMaps.push_back(std::make_pair(numLocalVars,subMap));
158 blockOffset += numLocalVars;
162 void buildExportImport(
const Epetra_Map & baseMap,
const std::vector<std::pair<
int,RCP<Epetra_Map> > > & subMaps,
163 std::vector<RCP<Epetra_Export> > & subExport,
164 std::vector<RCP<Epetra_Import> > & subImport)
166 std::vector<std::pair<int,RCP<Epetra_Map> > >::const_iterator mapItr;
169 for(mapItr=subMaps.begin();mapItr!=subMaps.end();++mapItr) {
171 const Epetra_Map & map = *(mapItr->second);
174 subImport.push_back(rcp(
new Epetra_Import(map,baseMap)));
175 subExport.push_back(rcp(
new Epetra_Export(map,baseMap)));
179 void buildSubVectors(
const std::vector<std::pair<
int,RCP<Epetra_Map> > > & subMaps,std::vector<RCP<Epetra_MultiVector> > & subVectors,
int count)
181 std::vector<std::pair<int,RCP<Epetra_Map> > >::const_iterator mapItr;
184 for(mapItr=subMaps.begin();mapItr!=subMaps.end();++mapItr) {
186 const Epetra_Map & map = *(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,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();++mapItr,++vecItr)
204 Teuchos::set_extra_data(mapItr->second,
"globalMap",Teuchos::inOutArg(*vecItr));
208 RCP<Epetra_CrsMatrix> buildSubBlock(
int i,
int j,
const Epetra_CrsMatrix & A,
const std::vector<std::pair<
int,RCP<Epetra_Map> > > & subMaps)
211 int numVarFamily = subMaps.size();
213 TEUCHOS_ASSERT(i>=0 && i<numVarFamily);
214 TEUCHOS_ASSERT(j>=0 && j<numVarFamily);
216 const Epetra_Map & gRowMap = *subMaps[i].second;
217 const Epetra_Map & rowMap = *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[i].second,
"contigMap");
218 const Epetra_Map & colMap = *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[j].second,
"contigMap");
219 int colFamilyCnt = subMaps[j].first;
223 int numGlobalVars = 0;
224 int rowBlockOffset = 0;
225 int colBlockOffset = 0;
226 for(
int k=0;k<numVarFamily;k++) {
227 numGlobalVars += subMaps[k].first;
230 if(k<i) rowBlockOffset += subMaps[k].first;
231 if(k<j) colBlockOffset += subMaps[k].first;
235 Epetra_Import
import(gRowMap,A.RowMap());
236 Epetra_CrsMatrix localA(Copy,gRowMap,0);
237 localA.Import(A,
import,Insert);
239 RCP<Epetra_CrsMatrix> mat = rcp(
new Epetra_CrsMatrix(Copy,rowMap,0));
242 int numMyRows = rowMap.NumMyElements();
243 int maxNumEntries = A.GlobalMaxNumEntries();
246 std::vector<int> indices(maxNumEntries);
247 std::vector<double> values(maxNumEntries);
250 std::vector<int> colIndices(maxNumEntries);
251 std::vector<double> colValues(maxNumEntries);
255 for(
int localRow=0;localRow<numMyRows;localRow++) {
257 int globalRow = gRowMap.GID(localRow);
258 int contigRow = rowMap.GID(localRow);
260 TEUCHOS_ASSERT(globalRow>=0);
261 TEUCHOS_ASSERT(contigRow>=0);
264 int err = localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]);
265 TEUCHOS_ASSERT(err==0);
267 int numOwnedCols = 0;
268 for(
int localCol=0;localCol<numEntries;localCol++) {
269 int globalCol = indices[localCol];
272 int block = globalCol / numGlobalVars;
274 bool inFamily =
true;
277 inFamily &= (block*numGlobalVars+colBlockOffset <= globalCol);
278 inFamily &= ((block*numGlobalVars+colBlockOffset+colFamilyCnt) > globalCol);
282 int familyOffset = globalCol-(block*numGlobalVars+colBlockOffset);
284 colIndices[numOwnedCols] = block*colFamilyCnt + familyOffset;
285 colValues[numOwnedCols] = values[localCol];
292 mat->InsertGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]);
296 mat->FillComplete(colMap,rowMap);
302 void rebuildSubBlock(
int i,
int j,
const Epetra_CrsMatrix & A,
const std::vector<std::pair<
int,RCP<Epetra_Map> > > & subMaps,Epetra_CrsMatrix & mat)
305 int numVarFamily = subMaps.size();
307 TEUCHOS_ASSERT(i>=0 && i<numVarFamily);
308 TEUCHOS_ASSERT(j>=0 && j<numVarFamily);
309 TEUCHOS_ASSERT(mat.Filled());
311 const Epetra_Map & gRowMap = *subMaps[i].second;
312 const Epetra_Map & rowMap = *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[i].second,
"contigMap");
313 int colFamilyCnt = subMaps[j].first;
317 int numGlobalVars = 0;
318 int rowBlockOffset = 0;
319 int colBlockOffset = 0;
320 for(
int k=0;k<numVarFamily;k++) {
321 numGlobalVars += subMaps[k].first;
324 if(k<i) rowBlockOffset += subMaps[k].first;
325 if(k<j) colBlockOffset += subMaps[k].first;
329 Epetra_Import
import(gRowMap,A.RowMap());
330 Epetra_CrsMatrix localA(Copy,gRowMap,0);
331 localA.Import(A,
import,Insert);
337 int numMyRows = rowMap.NumMyElements();
338 int maxNumEntries = A.GlobalMaxNumEntries();
341 std::vector<int> indices(maxNumEntries);
342 std::vector<double> values(maxNumEntries);
345 std::vector<int> colIndices(maxNumEntries);
346 std::vector<double> colValues(maxNumEntries);
350 for(
int localRow=0;localRow<numMyRows;localRow++) {
352 int globalRow = gRowMap.GID(localRow);
353 int contigRow = rowMap.GID(localRow);
355 TEUCHOS_ASSERT(globalRow>=0);
356 TEUCHOS_ASSERT(contigRow>=0);
359 int err = localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]);
360 TEUCHOS_ASSERT(err==0);
362 int numOwnedCols = 0;
363 for(
int localCol=0;localCol<numEntries;localCol++) {
364 int globalCol = indices[localCol];
367 int block = globalCol / numGlobalVars;
369 bool inFamily =
true;
372 inFamily &= (block*numGlobalVars+colBlockOffset <= globalCol);
373 inFamily &= ((block*numGlobalVars+colBlockOffset+colFamilyCnt) > globalCol);
377 int familyOffset = globalCol-(block*numGlobalVars+colBlockOffset);
379 colIndices[numOwnedCols] = block*colFamilyCnt + familyOffset;
380 colValues[numOwnedCols] = values[localCol];
387 mat.SumIntoGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]);
393 void many2one(Epetra_MultiVector & one,
const std::vector<RCP<const Epetra_MultiVector> > & many,
394 const std::vector<RCP<Epetra_Export> > & subExport)
397 std::vector<RCP<const Epetra_MultiVector> >::const_iterator vecItr;
398 std::vector<RCP<Epetra_Export> >::const_iterator expItr;
401 for(vecItr=many.begin(),expItr=subExport.begin();
402 vecItr!=many.end();++vecItr,++expItr) {
405 RCP<const Epetra_MultiVector> srcVec = *vecItr;
408 const Epetra_Map & globalMap = *(Teuchos::get_extra_data<RCP<Epetra_Map> >(srcVec,
"globalMap"));
411 Epetra_MultiVector exportVector(View,globalMap,srcVec->Values(),srcVec->Stride(),srcVec->NumVectors());
412 one.Export(exportVector,**expItr,Insert);
417 void one2many(std::vector<RCP<Epetra_MultiVector> > & many,
const Epetra_MultiVector & single,
418 const std::vector<RCP<Epetra_Import> > & subImport)
421 std::vector<RCP<Epetra_MultiVector> >::const_iterator vecItr;
422 std::vector<RCP<Epetra_Import> >::const_iterator impItr;
425 for(vecItr=many.begin(),impItr=subImport.begin();
426 vecItr!=many.end();++vecItr,++impItr) {
428 RCP<Epetra_MultiVector> destVec = *vecItr;
431 const Epetra_Map & globalMap = *(Teuchos::get_extra_data<RCP<Epetra_Map> >(destVec,
"globalMap"));
434 Epetra_MultiVector importVector(View,globalMap,destVec->Values(),destVec->Stride(),destVec->NumVectors());
437 importVector.Import(single,**impItr,Insert);