// rebuild a single subblock Epetra_CrsMatrix void rebuildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector<std::pair<int,RCP<Epetra_Map> > > & subMaps,Epetra_CrsMatrix & mat) { // get the number of variables families int numVarFamily = subMaps.size(); TEUCHOS_ASSERT(i>=0 && i<numVarFamily); TEUCHOS_ASSERT(j>=0 && j<numVarFamily); TEUCHOS_ASSERT(mat.Filled()); const Epetra_Map & gRowMap = *subMaps[i].second; const Epetra_Map & rowMap = *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[i].second,"contigMap"); int colFamilyCnt = subMaps[j].first; // compute the number of global variables // and the row and column block offset int numGlobalVars = 0; int rowBlockOffset = 0; int colBlockOffset = 0; for(int k=0;k<numVarFamily;k++) { numGlobalVars += subMaps[k].first; // compute block offsets if(k<i) rowBlockOffset += subMaps[k].first; if(k<j) colBlockOffset += subMaps[k].first; } // copy all global rows to here Epetra_Import import(gRowMap,A.RowMap()); Epetra_CrsMatrix localA(Copy,gRowMap,0); localA.Import(A,import,Insert); // clear out the old matrix mat.PutScalar(0.0); // get entry information int numMyRows = rowMap.NumMyElements(); int maxNumEntries = A.GlobalMaxNumEntries(); // for extraction std::vector<int> indices(maxNumEntries); std::vector<double> values(maxNumEntries); // for insertion std::vector<int> colIndices(maxNumEntries); std::vector<double> colValues(maxNumEntries); // insert each row into subblock // let FillComplete handle column distribution for(int localRow=0;localRow<numMyRows;localRow++) { int numEntries = -1; int globalRow = gRowMap.GID(localRow); int contigRow = rowMap.GID(localRow); TEUCHOS_ASSERT(globalRow>=0); TEUCHOS_ASSERT(contigRow>=0); // extract a global row copy int err = localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]); TEUCHOS_ASSERT(err==0); int numOwnedCols = 0; for(int localCol=0;localCol<numEntries;localCol++) { int globalCol = indices[localCol]; // determinate which block this column ID is in int block = globalCol / numGlobalVars; bool inFamily = true; // test the beginning of the block inFamily &= (block*numGlobalVars+colBlockOffset <= globalCol); inFamily &= ((block*numGlobalVars+colBlockOffset+colFamilyCnt) > globalCol); // is this column in the variable family if(inFamily) { int familyOffset = globalCol-(block*numGlobalVars+colBlockOffset); colIndices[numOwnedCols] = block*colFamilyCnt + familyOffset; colValues[numOwnedCols] = values[localCol]; numOwnedCols++; } } // insert it into the new matrix mat.SumIntoGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]); } }
int check(Epetra_CrsMatrix& A, int NumMyRows1, int NumGlobalRows1, int NumMyNonzeros1, int NumGlobalNonzeros1, int* MyGlobalElements, bool verbose) { (void)MyGlobalElements; int ierr = 0, forierr = 0; int NumGlobalIndices; int NumMyIndices; int* MyViewIndices = 0; int* GlobalViewIndices = 0; double* MyViewValues = 0; double* GlobalViewValues = 0; int MaxNumIndices = A.Graph().MaxNumIndices(); int* MyCopyIndices = new int[MaxNumIndices]; int* GlobalCopyIndices = new int[MaxNumIndices]; double* MyCopyValues = new double[MaxNumIndices]; double* GlobalCopyValues = new double[MaxNumIndices]; // Test query functions int NumMyRows = A.NumMyRows(); if (verbose) cout << "\n\nNumber of local Rows = " << NumMyRows << endl<< endl; EPETRA_TEST_ERR(!(NumMyRows==NumMyRows1),ierr); int NumMyNonzeros = A.NumMyNonzeros(); if (verbose) cout << "\n\nNumber of local Nonzero entries = " << NumMyNonzeros << endl<< endl; EPETRA_TEST_ERR(!(NumMyNonzeros==NumMyNonzeros1),ierr); int NumGlobalRows = A.NumGlobalRows(); if (verbose) cout << "\n\nNumber of global Rows = " << NumGlobalRows << endl<< endl; EPETRA_TEST_ERR(!(NumGlobalRows==NumGlobalRows1),ierr); int NumGlobalNonzeros = A.NumGlobalNonzeros(); if (verbose) cout << "\n\nNumber of global Nonzero entries = " << NumGlobalNonzeros << endl<< endl; EPETRA_TEST_ERR(!(NumGlobalNonzeros==NumGlobalNonzeros1),ierr); // GlobalRowView should be illegal (since we have local indices) EPETRA_TEST_ERR(!(A.ExtractGlobalRowView(A.RowMap().MaxMyGID(), NumGlobalIndices, GlobalViewValues, GlobalViewIndices)==-2),ierr); // Other binary tests EPETRA_TEST_ERR(A.NoDiagonal(),ierr); EPETRA_TEST_ERR(!(A.Filled()),ierr); EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MaxMyGID())),ierr); EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MinMyGID())),ierr); EPETRA_TEST_ERR(A.MyGRID(1+A.RowMap().MaxMyGID()),ierr); EPETRA_TEST_ERR(A.MyGRID(-1+A.RowMap().MinMyGID()),ierr); EPETRA_TEST_ERR(!(A.MyLRID(0)),ierr); EPETRA_TEST_ERR(!(A.MyLRID(NumMyRows-1)),ierr); EPETRA_TEST_ERR(A.MyLRID(-1),ierr); EPETRA_TEST_ERR(A.MyLRID(NumMyRows),ierr); forierr = 0; for (int i = 0; i < NumMyRows; i++) { int Row = A.GRID(i); A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyValues, GlobalCopyIndices); A.ExtractMyRowView(i, NumMyIndices, MyViewValues, MyViewIndices); // this is where the problem comes from forierr += !(NumGlobalIndices == NumMyIndices); for(int j = 1; j < NumMyIndices; j++) { forierr += !(MyViewIndices[j-1] < MyViewIndices[j]); // this is where the test fails } for(int j = 0; j < NumGlobalIndices; j++) { forierr += !(GlobalCopyIndices[j] == A.GCID(MyViewIndices[j])); forierr += !(A.LCID(GlobalCopyIndices[j]) == MyViewIndices[j]); forierr += !(GlobalCopyValues[j] == MyViewValues[j]); } } EPETRA_TEST_ERR(forierr,ierr); forierr = 0; for (int i = 0; i < NumMyRows; i++) { int Row = A.GRID(i); A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyValues, GlobalCopyIndices); A.ExtractMyRowCopy(i, MaxNumIndices, NumMyIndices, MyCopyValues, MyCopyIndices); forierr += !(NumGlobalIndices == NumMyIndices); for (int j = 1; j < NumMyIndices; j++) forierr += !(MyCopyIndices[j-1] < MyCopyIndices[j]); for (int j = 0; j < NumGlobalIndices; j++) { forierr += !(GlobalCopyIndices[j] == A.GCID(MyCopyIndices[j])); forierr += !(A.LCID(GlobalCopyIndices[j]) == MyCopyIndices[j]); forierr += !(GlobalCopyValues[j] == MyCopyValues[j]); } } EPETRA_TEST_ERR(forierr,ierr); delete [] MyCopyIndices; delete [] GlobalCopyIndices; delete [] MyCopyValues; delete [] GlobalCopyValues; if (verbose) cout << "\n\nRows sorted check OK" << endl<< endl; return (ierr); }