//---------------------------------------------------------------------------- Epetra_FEVector::~Epetra_FEVector() { destroyNonlocalData(); destroyNonlocalMapAndExporter(); nonlocalCoefs_.clear(); }
int EpetraVector<T>::GlobalAssemble(Epetra_CombineMode mode) { //In this method we need to gather all the non-local (overlapping) data //that's been input on each processor, into the (probably) non-overlapping //distribution defined by the map that 'this' vector was constructed with. //We don't need to do anything if there's only one processor or if //ignoreNonLocalEntries_ is true. if (_vec->Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) { return(0); } //First build a map that describes the data in nonlocalIDs_/nonlocalCoefs_. //We'll use the arbitrary distribution constructor of Map. Epetra_BlockMap sourceMap(-1, numNonlocalIDs_, nonlocalIDs_, nonlocalElementSize_, _vec->Map().IndexBase(), _vec->Map().Comm()); //Now build a vector to hold our nonlocalCoefs_, and to act as the source- //vector for our import operation. Epetra_MultiVector nonlocalVector(sourceMap, 1); int i,j; for(i=0; i<numNonlocalIDs_; ++i) { for(j=0; j<nonlocalElementSize_[i]; ++j) { nonlocalVector.ReplaceGlobalValue(nonlocalIDs_[i], j, 0, nonlocalCoefs_[i][j]); } } Epetra_Export exporter(sourceMap, _vec->Map()); EPETRA_CHK_ERR( _vec->Export(nonlocalVector, exporter, mode) ); destroyNonlocalData(); return(0); }
int Epetra_FEVector::GlobalAssemble(Epetra_CombineMode mode, bool reuse_map_and_exporter) { //In this method we need to gather all the non-local (overlapping) data //that's been input on each processor, into the (probably) non-overlapping //distribution defined by the map that 'this' vector was constructed with. //We don't need to do anything if there's only one processor or if //ignoreNonLocalEntries_ is true. if (Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) { return(0); } if (nonlocalMap_ == 0 || !reuse_map_and_exporter) { createNonlocalMapAndExporter<int_type>(); } Epetra_MultiVector& nonlocalVector = *nonlocalVector_; nonlocalVector.PutScalar(0.0); int elemSize = Map().MaxElementSize(); for(int vi=0; vi<NumVectors(); ++vi) { for(size_t i=0; i<nonlocalIDs<int_type>().size(); ++i) { for(int j=0; j<nonlocalElementSize_[i]; ++j) { nonlocalVector.ReplaceGlobalValue(nonlocalIDs<int_type>()[i], j, vi, nonlocalCoefs_[vi][i*elemSize+j]); } } } EPETRA_CHK_ERR( Export(nonlocalVector, *exporter_, mode) ); if (reuse_map_and_exporter) { zeroNonlocalData<int_type>(); } else { destroyNonlocalData(); } return(0); }
void EpetraVector<T>::FEoperatorequals(const EpetraVector & source) { (*_vec) = *(source._vec); destroyNonlocalData(); if (source.allocatedNonlocalLength_ > 0) { allocatedNonlocalLength_ = source.allocatedNonlocalLength_; numNonlocalIDs_ = source.numNonlocalIDs_; nonlocalIDs_ = new int[allocatedNonlocalLength_]; nonlocalElementSize_ = new int[allocatedNonlocalLength_]; nonlocalCoefs_ = new double *[allocatedNonlocalLength_]; for(int i=0; i<numNonlocalIDs_; ++i) { int elemSize = source.nonlocalElementSize_[i]; nonlocalCoefs_[i] = new double[elemSize]; nonlocalIDs_[i] = source.nonlocalIDs_[i]; nonlocalElementSize_[i] = elemSize; for(int j=0; j<elemSize; ++j) { nonlocalCoefs_[i][j] = source.nonlocalCoefs_[i][j]; } } } }
int Epetra_FEVbrMatrix::GlobalAssemble(bool callFillComplete) { if(Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) { if(callFillComplete) { EPETRA_CHK_ERR(FillComplete()); } return(0); } int i; //In this method we need to gather all the non-local (overlapping) data //that's been input on each processor, into the //non-overlapping distribution defined by the map that 'this' matrix was //constructed with. //Need to build a map that describes our nonlocal data. //First, create a list of the sizes (point-rows per block-row) of the //nonlocal rows we're holding. int* pointRowsPerNonlocalBlockRow = numNonlocalBlockRows_>0 ? new int[numNonlocalBlockRows_] : NULL; for(i=0; i<numNonlocalBlockRows_; ++i) { pointRowsPerNonlocalBlockRow[i] = nonlocalCoefs_[i][0]->M(); } //We'll use the arbitrary distribution constructor of BlockMap. Epetra_BlockMap sourceMap(-1, numNonlocalBlockRows_, nonlocalBlockRows_, // CJ TODO FIXME long long pointRowsPerNonlocalBlockRow, RowMap().IndexBase(), RowMap().Comm()); delete [] pointRowsPerNonlocalBlockRow; //If sourceMap has global size 0, then no nonlocal data exists and we can //skip most of this function. if(sourceMap.NumGlobalElements64() < 1) { if(callFillComplete) { EPETRA_CHK_ERR(FillComplete()); } return(0); } //We also need to build a column-map, containing the columns in our //nonlocal data. To do that, create a list of all column-indices that //occur in our nonlocal rows. int numCols = 0, allocLen = 0; int* cols = NULL; int* pointColsPerBlockCol = NULL; int ptColAllocLen = 0; int insertPoint = -1; for(i=0; i<numNonlocalBlockRows_; ++i) { for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) { int col = nonlocalBlockCols_[i][j]; int offset = Epetra_Util_binary_search(col, cols, numCols, insertPoint); if (offset < 0) { EPETRA_CHK_ERR( Epetra_Util_insert(col, insertPoint, cols, numCols, allocLen) ); int tmpNumCols = numCols-1; EPETRA_CHK_ERR( Epetra_Util_insert(nonlocalCoefs_[i][j]->N(), insertPoint, pointColsPerBlockCol, tmpNumCols, ptColAllocLen) ); } } } Epetra_BlockMap colMap(-1, numCols, cols, // CJ TODO FIXME long long pointColsPerBlockCol, RowMap().IndexBase(), RowMap().Comm()); delete [] cols; delete [] pointColsPerBlockCol; numCols = 0; allocLen = 0; //now we need to create a matrix with sourceMap and colMap, and fill it with //our nonlocal data so we can then export it to the correct owning //processors. Epetra_VbrMatrix tempMat(Copy, sourceMap, colMap, nonlocalBlockRowLengths_); //Next we need to make sure the 'indices-are-global' attribute of tempMat's //graph is set to true, in case this processor doesn't end up calling the //InsertGlobalValues method... const Epetra_CrsGraph& graph = tempMat.Graph(); Epetra_CrsGraph& nonconst_graph = const_cast<Epetra_CrsGraph&>(graph); nonconst_graph.SetIndicesAreGlobal(true); for(i=0; i<numNonlocalBlockRows_; ++i) { EPETRA_CHK_ERR( tempMat.BeginInsertGlobalValues(nonlocalBlockRows_[i], nonlocalBlockRowLengths_[i], nonlocalBlockCols_[i]) ); for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) { Epetra_SerialDenseMatrix& subblock = *(nonlocalCoefs_[i][j]); EPETRA_CHK_ERR( tempMat.SubmitBlockEntry(subblock.A(), subblock.LDA(), subblock.M(), subblock.N()) ); } EPETRA_CHK_ERR( tempMat.EndSubmitEntries() ); } //Now we need to call FillComplete on our temp matrix. We need to //pass a DomainMap and RangeMap, which are not the same as the RowMap //and ColMap that we constructed the matrix with. EPETRA_CHK_ERR(tempMat.FillComplete(RowMap(), sourceMap)); //Finally, we're ready to create the exporter and export non-local data to //the appropriate owning processors. Epetra_Export exporter(sourceMap, RowMap()); EPETRA_CHK_ERR( Export(tempMat, exporter, Add) ); if(callFillComplete) { EPETRA_CHK_ERR(FillComplete()); } destroyNonlocalData(); return(0); }
//---------------------------------------------------------------------------- Epetra_FEVbrMatrix::~Epetra_FEVbrMatrix() { destroyNonlocalData(); }