00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <algorithm>
00014 #include <vector>
00015 #include <set>
00016 #include "rlog/rlog.h"
00017 #include "Epetra_Comm.h"
00018 #include "Epetra_CrsMatrix.h"
00019 #include "Epetra_FECrsMatrix.h"
00020 #include "Epetra_Export.h"
00021 #include "Epetra_Import.h"
00022 #include "Epetra_Map.h"
00023 #include "matrix_matrix.h"
00024
00025 #define USE_MM_COLMAP 1
00026
00027 using namespace std;
00028
00031 static void bext_map_1(const Epetra_CrsMatrix& A, std::vector<int>& col_indices) {
00032 for (int i_local = 0; i_local < A.NumMyRows(); ++ i_local) {
00033 int info;
00034 int num_entries_A;
00035 double *values_A;
00036 int *indices_A;
00037
00038
00039 info = A.ExtractMyRowView(i_local, num_entries_A, values_A, indices_A);
00040 rAssert(info == 0);
00041
00042
00043 for (int k = 0; k < num_entries_A; ++ k) {
00044 int j_global = A.GCID(indices_A[k]);
00045
00046
00047 std::vector<int>::iterator found_it;
00048 found_it = std::find(col_indices.begin(),
00049 col_indices.end(),
00050 j_global);
00051 if (found_it == col_indices.end()) {
00052 col_indices.push_back(j_global);
00053 }
00054 }
00055
00056 }
00057 }
00058
00061 static void bext_map_2(const Epetra_CrsMatrix& A, std::vector<int>& col_indices) {
00062 for (int i_local = 0; i_local < A.NumMyRows(); ++ i_local) {
00063 int info;
00064 int num_entries_A;
00065 double *values_A;
00066 int *indices_A;
00067
00068
00069 info = A.ExtractMyRowView(i_local, num_entries_A, values_A, indices_A);
00070 rAssert(info == 0);
00071
00072
00073 for (int k = 0; k < num_entries_A; ++ k) {
00074 int j_global = A.GCID(indices_A[k]);
00075 col_indices.push_back(j_global);
00076 }
00077
00078 }
00079 std::sort(col_indices.begin(), col_indices.end());
00080 std::vector<int>::iterator erase_it = std::unique(col_indices.begin(), col_indices.end());
00081 col_indices.erase(erase_it, col_indices.end());
00082 }
00083
00086 static void bext_map_3(const Epetra_CrsMatrix& A, std::vector<int>& col_indices) {
00087 std::set<int> set_B;
00088 for (int i_local = 0; i_local < A.NumMyRows(); ++ i_local) {
00089 int info;
00090 int num_entries_A;
00091 double *values_A;
00092 int *indices_A;
00093
00094
00095 info = A.ExtractMyRowView(i_local, num_entries_A, values_A, indices_A);
00096 rAssert(info == 0);
00097
00098
00099 for (int k = 0; k < num_entries_A; ++ k) {
00100 int j_global = A.GCID(indices_A[k]);
00101 set_B.insert(j_global);
00102 }
00103
00104 }
00105
00106 col_indices.reserve(set_B.size());
00107 for (std::set<int>::iterator it = set_B.begin();
00108 it != set_B.end();
00109 ++ it)
00110 {
00111 col_indices.push_back(*it);
00112 }
00113 }
00114
00116 int poor_man_matrix_matrix(const Epetra_CrsMatrix& A, const Epetra_CrsMatrix& B, Epetra_CrsMatrix& C) {
00117 int info;
00118
00119 if (A.Comm().NumProc() == 1) {
00120
00121 return poor_man_matrix_matrix_local(A, B, C);
00122 }
00123
00124
00125
00126 #ifdef USE_MM_COLMAP
00127 Epetra_Map map_B(A.ColMap());
00128 #else
00129
00130 std::vector<int> indices_B;
00131 bext_map_3(A, indices_B);
00132 rDebug("%d: poor_man_matrix_matrix: local rows: %d -> %d",
00133 A.Comm().MyPID(), B.NumMyRows(), indices_B.size());
00134 rDebug("%d: poor_man_matrix_matrix: column map size: %d",
00135 A.Comm().MyPID(), A.ColMap().NumMyElements());
00136 Epetra_Map map_B(-1, indices_B.size(), &indices_B[0], 0, A.Comm());
00137 #endif
00138
00139
00140 Epetra_Import plan_B(map_B, B.RowMap());
00141 Epetra_CrsMatrix Bext(Copy, map_B, 0);
00142 info = Bext.Import(B, plan_B, Insert);
00143 rAssert(info == 0);
00144 info = Bext.FillComplete(B.DomainMap(), B.RangeMap());
00145 rAssert(info == 0);
00146
00147
00148 for (int i_local = 0; i_local < A.NumMyRows(); ++ i_local) {
00149
00150 int num_entries_A, num_entries_B;
00151 double *values_A, *values_B;
00152 int *indices_A, *indices_B;
00153 info = A.ExtractMyRowView(i_local, num_entries_A, values_A, indices_A);
00154 rAssert(info == 0);
00155
00156
00157 for (int k = 0; k < num_entries_A; ++ k) {
00158 int j_global = A.GCID(indices_A[k]);
00159 rAssert(Bext.MyGRID(j_global));
00160 info = Bext.ExtractMyRowView(Bext.LRID(j_global), num_entries_B, values_B, indices_B);
00161 rAssert(info == 0);
00162 for (int l = 0; l < num_entries_B; ++ l) {
00163 double value = values_A[k] * values_B[l];
00164 int index = Bext.GCID(indices_B[l]);
00165 info = C.SumIntoGlobalValues(A.GRID(i_local), 1, &value, &index);
00166 if (info > 0)
00167 info = C.InsertGlobalValues(A.GRID(i_local), 1, &value, &index);
00168 rAssert(info >= 0);
00169 }
00170 }
00171
00172 }
00173 info = C.FillComplete(B.OperatorDomainMap(), A.OperatorRangeMap());
00174 rAssert(info >= 0);
00175 return 0;
00176 }
00177
00180 int poor_man_matrix_matrix_local(const Epetra_CrsMatrix& A, const Epetra_CrsMatrix& B, Epetra_CrsMatrix& C) {
00181 int info;
00182
00183
00184 for (int i_local = 0; i_local < A.NumMyRows(); ++ i_local) {
00185
00186 int num_entries_A, num_entries_B;
00187 double *values_A, *values_B;
00188 int *indices_A, *indices_B;
00189 info = A.ExtractMyRowView(i_local, num_entries_A, values_A, indices_A);
00190 rAssert(info == 0);
00191
00192
00193 for (int k = 0; k < num_entries_A; ++ k) {
00194 int j_global = A.GCID(indices_A[k]);
00195 if (B.MyGRID(j_global)) {
00196
00197 info = B.ExtractMyRowView(B.LRID(j_global), num_entries_B, values_B, indices_B);
00198 rAssert(info == 0);
00199 for (int l = 0; l < num_entries_B; ++ l) {
00200 double value = values_A[k] * values_B[l];
00201 int index = B.GCID(indices_B[l]);
00202 info = C.SumIntoGlobalValues(A.GRID(i_local), 1, &value, &index);
00203 if (info > 0)
00204 info = C.InsertGlobalValues(A.GRID(i_local), 1, &value, &index);
00205 rAssert(info >= 0);
00206 }
00207 }
00208 }
00209
00210 }
00211 info = C.FillComplete(B.OperatorDomainMap(), A.OperatorRangeMap());
00212 rAssert(info >= 0);
00213 return 0;
00214 }
00215
00217 int poor_man_matrix_matrix_graph(const Epetra_CrsGraph& A, const Epetra_CrsGraph& B, Epetra_CrsGraph& C) {
00218 int max_nnz_B = B.MaxNumIndices();
00219 vector<int> ind_B(max_nnz_B);
00220 int *indices_B = &ind_B[0];
00221
00222
00223 for (int i_local = 0; i_local < A.NumMyRows(); ++ i_local) {
00224
00225 int num_entries_A, num_entries_B;
00226 int *indices_A;
00227 int info;
00228 info = A.ExtractMyRowView(i_local, num_entries_A, indices_A);
00229 rAssert(info == 0);
00230
00231
00232 for (int k = 0; k < num_entries_A; ++ k) {
00233 int j_global = A.GCID(indices_A[k]);
00234 if (B.MyGRID(j_global)) {
00235
00236 info = B.ExtractMyRowCopy(B.LRID(j_global), max_nnz_B, num_entries_B, indices_B);
00237 rAssert(info == 0);
00238
00239 for (int l = 0; l < num_entries_B; ++ l)
00240 indices_B[l] = B.GCID(indices_B[l]);
00241
00242 info = C.InsertGlobalIndices(A.GRID(i_local), num_entries_B, indices_B);
00243 rAssert(info >= 0);
00244 }
00245 }
00246 }
00247 return 0;
00248 }
00249
00253 int poor_man_matrix_matrix_local2(const Epetra_CrsMatrix& A, const Epetra_CrsMatrix& B, Epetra_CrsMatrix& C) {
00254 int info;
00255
00256 int max_nnz_B = B.MaxNumEntries();
00257 vector<int> ind_B(max_nnz_B);
00258 vector<double> val_B(max_nnz_B);
00259 double *values_B = &val_B[0];
00260 int *indices_B = &ind_B[0];
00261
00262
00263
00264
00265
00266 for (int i_local = 0; i_local < A.NumMyRows(); ++ i_local) {
00267
00268 int num_entries_A, num_entries_B;
00269 double *values_A;
00270 int *indices_A;
00271 info = A.ExtractMyRowView(i_local, num_entries_A, values_A, indices_A);
00272 rAssert(info == 0);
00273
00274
00275 for (int k = 0; k < num_entries_A; ++ k) {
00276 int j_global = A.GCID(indices_A[k]);
00277 if (B.MyGRID(j_global)) {
00278
00279 info = B.ExtractMyRowCopy(B.LRID(j_global), max_nnz_B, num_entries_B, values_B, indices_B);
00280 rAssert(info == 0);
00281
00282 for (int l = 0; l < num_entries_B; ++ l)
00283 values_B[l] *= values_A[k];
00284
00285 info = C.SumIntoMyValues(i_local, num_entries_B, values_B, indices_B);
00286 if (info != 0)
00287 rDebug("info=%d", info);
00288 rAssert(info == 0);
00289 }
00290 }
00291
00292 }
00293 info = C.FillComplete(B.OperatorDomainMap(), A.OperatorRangeMap());
00294 rAssert(info >= 0);
00295 return 0;
00296 }
00297
00298 int transpose_matrix(const Epetra_CrsMatrix& A, Epetra_FECrsMatrix& T) {
00299 int info;
00300
00301 for (int lrow = 0; lrow < A.NumMyRows(); lrow ++) {
00302 int grow = A.RowMap().GID(lrow);
00303 int nof_entries;
00304 int* col;
00305 double* val;
00306 info = A.ExtractMyRowView(lrow, nof_entries, val, col);
00307 rAssert(info == 0);
00308
00309 for (int k = 0; k < nof_entries; k ++) {
00310 int gcol = A.ColMap().GID(col[k]);
00311 info = T.InsertGlobalValues(1, &gcol, 1, &grow, val+k);
00312 rAssert(info >= 0);
00313 }
00314 }
00315
00316 info = T.GlobalAssemble(false);
00317 rAssert(info == 0);
00318 info = T.FillComplete(A.OperatorRangeMap(), A.OperatorDomainMap());
00319 rAssert(info == 0);
00320 return 0;
00321 }