00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "EpetraExt_BlockCrsMatrix.h"
00030 #include "EpetraExt_BlockUtility.h"
00031 #include "Epetra_Map.h"
00032
00033 namespace EpetraExt {
00034
00035 using std::vector;
00036
00037
00038 BlockCrsMatrix::BlockCrsMatrix(
00039 const Epetra_CrsGraph & BaseGraph,
00040 const vector<int> & RowStencil,
00041 int RowIndex,
00042 const Epetra_Comm & GlobalComm )
00043 : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseGraph, vector< vector<int> >(1,RowStencil), vector<int>(1,RowIndex), GlobalComm )) ),
00044 BaseGraph_( BaseGraph ),
00045 RowStencil_( vector< vector<int> >(1,RowStencil) ),
00046 RowIndices_( vector<int>(1,RowIndex) ),
00047 Offset_(BlockUtility::CalculateOffset(BaseGraph.RowMap()))
00048 {
00049 }
00050
00051
00052 BlockCrsMatrix::BlockCrsMatrix(
00053 const Epetra_CrsGraph & BaseGraph,
00054 const vector< vector<int> > & RowStencil,
00055 const vector<int> & RowIndices,
00056 const Epetra_Comm & GlobalComm )
00057 : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseGraph, RowStencil, RowIndices, GlobalComm )) ),
00058 BaseGraph_( BaseGraph ),
00059 RowStencil_( RowStencil ),
00060 RowIndices_( RowIndices ),
00061 Offset_(BlockUtility::CalculateOffset(BaseGraph.RowMap()))
00062 {
00063 }
00064
00065
00066 BlockCrsMatrix::BlockCrsMatrix(
00067 const Epetra_RowMatrix & BaseMatrix,
00068 const vector< vector<int> > & RowStencil,
00069 const vector<int> & RowIndices,
00070 const Epetra_Comm & GlobalComm )
00071 : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseMatrix, RowStencil, RowIndices, GlobalComm )) ),
00072 BaseGraph_( Copy, BaseMatrix.RowMatrixRowMap(), 1 ),
00073 RowStencil_( RowStencil ),
00074 RowIndices_( RowIndices ),
00075 Offset_(BlockUtility::CalculateOffset(BaseMatrix.RowMatrixRowMap()))
00076 {
00077 }
00078
00079
00080 BlockCrsMatrix::BlockCrsMatrix( const BlockCrsMatrix & Matrix )
00081 : Epetra_CrsMatrix( dynamic_cast<const Epetra_CrsMatrix &>( Matrix ) ),
00082 BaseGraph_( Matrix.BaseGraph_ ),
00083 RowStencil_( Matrix.RowStencil_ ),
00084 RowIndices_( Matrix.RowIndices_ ),
00085 Offset_( Matrix.Offset_ )
00086 {
00087 }
00088
00089
00090 BlockCrsMatrix::~BlockCrsMatrix()
00091 {
00092 }
00093
00094
00095 void BlockCrsMatrix::LoadBlock(const Epetra_RowMatrix & BaseMatrix, const int Row, const int Col)
00096 {
00097 int RowOffset = RowIndices_[Row] * Offset_;
00098 int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00099
00100
00101 const Epetra_BlockMap & BaseMap = BaseMatrix.RowMatrixRowMap();
00102 const Epetra_BlockMap & BaseColMap = BaseMatrix.RowMatrixColMap();
00103
00104
00105
00106
00107
00108 int MaxIndices = BaseMatrix.MaxNumEntries();
00109 vector<int> Indices(MaxIndices);
00110 vector<double> Values(MaxIndices);
00111 int NumIndices;
00112 int ierr=0;
00113
00114 for (int i=0; i<BaseMap.NumMyElements(); i++) {
00115 BaseMatrix.ExtractMyRowCopy( i, MaxIndices, NumIndices, &Values[0], &Indices[0] );
00116
00117
00118 for( int l = 0; l < NumIndices; ++l )
00119 Indices[l] = ColOffset + BaseColMap.GID(Indices[l]);
00120
00121 int BaseRow = BaseMap.GID(i);
00122 ierr = this->ReplaceGlobalValues(BaseRow + RowOffset, NumIndices, &Values[0], &Indices[0]);
00123 if (ierr != 0) cout << "WARNING BlockCrsMatrix::LoadBlock ReplaceGlobalValues err = " << ierr <<
00124 "\n\t Row " << BaseRow + RowOffset << "Col start" << Indices[0] << endl;
00125
00126 }
00127 }
00128
00129
00130 void BlockCrsMatrix::BlockSumIntoGlobalValues(const int BaseRow, int NumIndices,
00131 double* Values, const int* Indices, const int Row, const int Col)
00132
00133 {
00134 int RowOffset = RowIndices_[Row] * Offset_;
00135 int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00136
00137
00138 vector<int> OffsetIndices(NumIndices);
00139 for( int l = 0; l < NumIndices; ++l ) OffsetIndices[l] = Indices[l] + ColOffset;
00140
00141 int ierr = this->SumIntoGlobalValues(BaseRow + RowOffset, NumIndices,
00142 Values, &OffsetIndices[0]);
00143
00144 if (ierr != 0) cout << "WARNING BlockCrsMatrix::BlockSumIntoGlobalValues err = "
00145 << ierr << "\n\t Row " << BaseRow + RowOffset << "Col start" << Indices[0] << endl;
00146 }
00147
00148
00149 void BlockCrsMatrix::BlockReplaceGlobalValues(const int BaseRow, int NumIndices,
00150 double* Values, const int* Indices, const int Row, const int Col)
00151
00152 {
00153 int RowOffset = RowIndices_[Row] * Offset_;
00154 int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00155
00156
00157 vector<int> OffsetIndices(NumIndices);
00158 for( int l = 0; l < NumIndices; ++l ) OffsetIndices[l] = Indices[l] + ColOffset;
00159
00160 int ierr = this->ReplaceGlobalValues(BaseRow + RowOffset, NumIndices,
00161 Values, &OffsetIndices[0]);
00162
00163 if (ierr != 0) cout << "WARNING BlockCrsMatrix::BlockReplaceGlobalValues err = "
00164 << ierr << "\n\t Row " << BaseRow + RowOffset << "Col start" << Indices[0] << endl;
00165 }
00166
00167
00168 void BlockCrsMatrix::BlockExtractGlobalRowView(const int BaseRow,
00169 int& NumEntries,
00170 double*& Values,
00171 const int Row,
00172 const int Col)
00173
00174 {
00175 int RowOffset = RowIndices_[Row] * Offset_;
00176 int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00177
00178
00179 int ierr = this->ExtractGlobalRowView(BaseRow + RowOffset, NumEntries,
00180 Values);
00181
00182
00183 Values += ColOffset;
00184 NumEntries -= ColOffset;
00185
00186 if (ierr != 0) cout << "WARNING BlockCrsMatrix::BlockExtractGlobalRowView err = "
00187 << ierr << "\n\t Row " << BaseRow + RowOffset << "Col " << Col+ColOffset << endl;
00188 }
00189
00190
00191 void BlockCrsMatrix::ExtractBlock(Epetra_CrsMatrix & BaseMatrix, const int Row, const int Col)
00192 {
00193 int RowOffset = RowIndices_[Row] * Offset_;
00194 int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00195
00196
00197 const Epetra_BlockMap & BaseMap = BaseMatrix.RowMatrixRowMap();
00198
00199
00200
00201
00202
00203
00204 int MaxIndices = BaseMatrix.MaxNumEntries();
00205 vector<int> Indices(MaxIndices);
00206 vector<double> Values(MaxIndices);
00207 int NumIndices;
00208 int indx,icol;
00209 double* BlkValues;
00210 int *BlkIndices;
00211 int BlkNumIndices;
00212 int ierr=0;
00213
00214 for (int i=0; i<BaseMap.NumMyElements(); i++) {
00215
00216
00217 int BaseRow = BaseMap.GID(i);
00218 int myBlkBaseRow = this->RowMatrixRowMap().LID(BaseRow + RowOffset);
00219 ierr = this->ExtractMyRowView(myBlkBaseRow, BlkNumIndices, BlkValues, BlkIndices);
00220
00221 NumIndices = 0;
00222
00223 for( int l = 0; l < BlkNumIndices; ++l ) {
00224 icol = this->RowMatrixColMap().GID(BlkIndices[l]);
00225 indx = icol - ColOffset;
00226 if (indx >= 0 && indx < Offset_) {
00227 Indices[NumIndices] = indx;
00228 Values[NumIndices] = BlkValues[l];
00229 NumIndices++;
00230 }
00231 }
00232
00233
00234 BaseMatrix.ReplaceGlobalValues(BaseRow, NumIndices, &Values[0], &Indices[0] );
00235
00236 }
00237 }
00238
00239 }