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_BlockUtility.h"
00030 #include "Epetra_Map.h"
00031 #include "Epetra_Comm.h"
00032
00033 namespace EpetraExt {
00034
00035 using std::vector;
00036
00037
00038 Epetra_Map * BlockUtility::GenerateBlockMap(
00039 const Epetra_BlockMap & BaseMap,
00040 const vector<int> & RowIndices,
00041 const Epetra_Comm & GlobalComm )
00042 {
00043 int BaseIndex = BaseMap.IndexBase();
00044 int Offset = BlockUtility::CalculateOffset(BaseMap);
00045
00046
00047 int NumBlockRows = RowIndices.size();
00048 int Size = BaseMap.NumMyElements();
00049 int TotalSize = NumBlockRows * Size;
00050 vector<int> GIDs(Size);
00051 BaseMap.MyGlobalElements( &GIDs[0] );
00052
00053 vector<int> GlobalGIDs( TotalSize );
00054 for( int i = 0; i < NumBlockRows; ++i )
00055 {
00056 for( int j = 0; j < Size; ++j )
00057 GlobalGIDs[i*Size+j] = GIDs[j] + RowIndices[i] * Offset;
00058 }
00059
00060 int GlobalSize;
00061 GlobalComm.SumAll( &TotalSize, &GlobalSize, 1 );
00062
00063 Epetra_Map *GlobalMap =
00064 new Epetra_Map( GlobalSize, TotalSize, &GlobalGIDs[0], BaseIndex,
00065 GlobalComm );
00066
00067 return GlobalMap;
00068 }
00069
00070
00071 Epetra_CrsGraph * BlockUtility::GenerateBlockGraph(
00072 const Epetra_CrsGraph & BaseGraph,
00073 const vector< vector<int> > & RowStencil,
00074 const vector<int> & RowIndices,
00075 const Epetra_Comm & GlobalComm )
00076 {
00077
00078 const Epetra_BlockMap & BaseMap = BaseGraph.RowMap();
00079 int BaseIndex = BaseMap.IndexBase();
00080 int Offset = BlockUtility::CalculateOffset(BaseMap);
00081
00082
00083 int NumBlockRows = RowIndices.size();
00084 int Size = BaseMap.NumMyElements();
00085 int TotalSize = NumBlockRows * Size;
00086 vector<int> GIDs(Size);
00087 BaseMap.MyGlobalElements( &GIDs[0] );
00088
00089 vector<int> GlobalGIDs( TotalSize );
00090 for( int i = 0; i < NumBlockRows; ++i )
00091 {
00092 for( int j = 0; j < Size; ++j )
00093 GlobalGIDs[i*Size+j] = GIDs[j] + RowIndices[i] * Offset;
00094 }
00095
00096 int GlobalSize;
00097 GlobalComm.SumAll( &TotalSize, &GlobalSize, 1 );
00098
00099 Epetra_Map GlobalMap( GlobalSize, TotalSize, &GlobalGIDs[0], BaseIndex, GlobalComm );
00100
00101 int MaxIndices = BaseGraph.MaxNumIndices();
00102 vector<int> Indices(MaxIndices);
00103 int NumIndices;
00104
00105 Epetra_CrsGraph * GlobalGraph = new Epetra_CrsGraph( Copy,
00106 dynamic_cast<Epetra_BlockMap&>(GlobalMap),
00107 0 );
00108
00109 for( int i = 0; i < NumBlockRows; ++i )
00110 {
00111 int StencilSize = RowStencil[i].size();
00112 for( int j = 0; j < Size; ++j )
00113 {
00114 int BaseRow = BaseMap.GID(j);
00115 int GlobalRow = GlobalMap.GID(j+i*Size);
00116
00117 BaseGraph.ExtractGlobalRowCopy( BaseRow, MaxIndices, NumIndices, &Indices[0] );
00118 for( int k = 0; k < StencilSize; ++k )
00119 {
00120 int ColOffset = (RowIndices[i]+RowStencil[i][k]) * Offset;
00121 if( k > 0 ) ColOffset -= (RowIndices[i]+RowStencil[i][k-1]) * Offset;
00122
00123 for( int l = 0; l < NumIndices; ++l )
00124 Indices[l] += ColOffset;
00125
00126 GlobalGraph->InsertGlobalIndices( GlobalRow, NumIndices, &Indices[0] );
00127 }
00128 }
00129 }
00130
00131 GlobalGraph->FillComplete();
00132
00133 return GlobalGraph;
00134 }
00135
00136
00137 Epetra_CrsGraph * BlockUtility::GenerateBlockGraph(
00138 const Epetra_RowMatrix & BaseMatrix,
00139 const vector< vector<int> > & RowStencil,
00140 const vector<int> & RowIndices,
00141 const Epetra_Comm & GlobalComm )
00142 {
00143
00144 const Epetra_BlockMap & BaseMap = BaseMatrix.RowMatrixRowMap();
00145 const Epetra_BlockMap & BaseColMap = BaseMatrix.RowMatrixColMap();
00146 int BaseIndex = BaseMap.IndexBase();
00147 int Offset = BlockUtility::CalculateOffset(BaseMap);
00148
00149
00150 int NumBlockRows = RowIndices.size();
00151 int Size = BaseMap.NumMyElements();
00152 int TotalSize = NumBlockRows * Size;
00153 vector<int> GIDs(Size);
00154 BaseMap.MyGlobalElements( &GIDs[0] );
00155
00156 vector<int> GlobalGIDs( TotalSize );
00157 for( int i = 0; i < NumBlockRows; ++i )
00158 {
00159 for( int j = 0; j < Size; ++j )
00160 GlobalGIDs[i*Size+j] = GIDs[j] + RowIndices[i] * Offset;
00161 }
00162
00163 int GlobalSize;
00164 GlobalComm.SumAll( &TotalSize, &GlobalSize, 1 );
00165
00166 Epetra_Map GlobalMap( GlobalSize, TotalSize, &GlobalGIDs[0], BaseIndex, GlobalComm );
00167
00168 int MaxIndices = BaseMatrix.MaxNumEntries();
00169 vector<int> Indices(MaxIndices);
00170 vector<double> Values(MaxIndices);
00171 int NumIndices;
00172
00173 Epetra_CrsGraph * GlobalGraph = new Epetra_CrsGraph( Copy,
00174 dynamic_cast<Epetra_BlockMap&>(GlobalMap),
00175 0 );
00176
00177 for( int i = 0; i < NumBlockRows; ++i )
00178 {
00179 int StencilSize = RowStencil[i].size();
00180 for( int j = 0; j < Size; ++j )
00181 {
00182 int GlobalRow = GlobalMap.GID(j+i*Size);
00183
00184 BaseMatrix.ExtractMyRowCopy( j, MaxIndices, NumIndices, &Values[0], &Indices[0] );
00185 for( int l = 0; l < NumIndices; ++l ) Indices[l] = BaseColMap.GID(Indices[l]);
00186
00187 for( int k = 0; k < StencilSize; ++k )
00188 {
00189 int ColOffset = (RowIndices[i]+RowStencil[i][k]) * Offset;
00190 if( k > 0 ) ColOffset -= (RowIndices[i]+RowStencil[i][k-1]) * Offset;
00191
00192 for( int l = 0; l < NumIndices; ++l )
00193 Indices[l] += ColOffset;
00194
00195 GlobalGraph->InsertGlobalIndices( GlobalRow, NumIndices, &Indices[0] );
00196 }
00197 }
00198 }
00199
00200 GlobalGraph->FillComplete();
00201
00202 return GlobalGraph;
00203 }
00204
00205
00206 int BlockUtility::CalculateOffset(const Epetra_BlockMap & BaseMap)
00207 {
00208 int MaxGID = BaseMap.MaxAllGID();
00209
00210
00211
00212
00213
00214
00215 return MaxGID+1;
00216 }
00217
00218
00219 }