void Transpose (const Table &A, Table &At, int _ncols_A) { const int *i_A = A.GetI(); const int *j_A = A.GetJ(); const int nrows_A = A.Size(); const int ncols_A = (_ncols_A < 0) ? A.Width() : _ncols_A; const int nnz_A = i_A[nrows_A]; At.SetDims (ncols_A, nnz_A); int *i_At = At.GetI(); int *j_At = At.GetJ(); for (int i = 0; i <= ncols_A; i++) i_At[i] = 0; for (int i = 0; i < nnz_A; i++) i_At[j_A[i]+1]++; for (int i = 1; i < ncols_A; i++) i_At[i+1] += i_At[i]; for (int i = 0; i < nrows_A; i++) for (int j = i_A[i]; j < i_A[i+1]; j++) j_At[i_At[j_A[j]]++] = i; for (int i = ncols_A; i > 0; i--) i_At[i] = i_At[i-1]; i_At[0] = 0; }
void UpdateElementToVertexTable() { if (element_vertex.Size() < 0) { BuildElementToVertexTable(); } }
void Mult (const Table &A, const Table &B, Table &C) { int i, j, k, l, m; const int *i_A = A.GetI(); const int *j_A = A.GetJ(); const int *i_B = B.GetI(); const int *j_B = B.GetJ(); const int nrows_A = A.Size(); const int nrows_B = B.Size(); const int ncols_A = A.Width(); const int ncols_B = B.Width(); MFEM_VERIFY( ncols_A <= nrows_B, "Table size mismatch: ncols_A = " << ncols_A << ", nrows_B = " << nrows_B); Array<int> B_marker (ncols_B); for (i = 0; i < ncols_B; i++) B_marker[i] = -1; int counter = 0; for (i = 0; i < nrows_A; i++) { for (j = i_A[i]; j < i_A[i+1]; j++) { k = j_A[j]; for (l = i_B[k]; l < i_B[k+1]; l++) { m = j_B[l]; if (B_marker[m] != i) { B_marker[m] = i; counter++; } } } } C.SetDims (nrows_A, counter); for (i = 0; i < ncols_B; i++) B_marker[i] = -1; int *i_C = C.GetI(); int *j_C = C.GetJ(); counter = 0; for (i = 0; i < nrows_A; i++) { i_C[i] = counter; for (j = i_A[i]; j < i_A[i+1]; j++) { k = j_A[j]; for (l = i_B[k]; l < i_B[k+1]; l++) { m = j_B[l]; if (B_marker[m] != i) { B_marker[m] = i; j_C[counter] = m; counter++; } } } } }