28 const Table &table2,
int offset)
30 MFEM_ASSERT(table1.
size == table2.
size,
31 "Tables have different sizes can not merge.");
34 const int nnz = table1.
I[
size] + table2.
I[
size];
40 for (
int i = 0; i <
size; i++)
45 for (
int r = 0; r < row.
Size(); r++,
I[i+1] ++)
51 for (
int r = 0; r < row.
Size(); r++,
I[i+1] ++)
53 J[
I[i+1] ] = (row[r] < 0) ? row[r] - offset : row[r] + offset;
60 const Table &table2,
int offset2,
61 const Table &table3,
int offset3)
63 MFEM_ASSERT(table1.
size == table2.
size,
64 "Tables have different sizes can not merge.");
65 MFEM_ASSERT(table1.
size == table3.
size,
66 "Tables have different sizes can not merge.");
75 for (
int i = 0; i <
size; i++)
80 for (
int r = 0; r < row.
Size(); r++,
I[i+1] ++)
86 for (
int r = 0; r < row.
Size(); r++,
I[i+1] ++)
88 J[
I[i+1] ] = (row[r] < 0) ? row[r] - offset2 : row[r] + offset2;
92 for (
int r = 0; r < row.
Size(); r++,
I[i+1] ++)
94 J[
I[i+1] ] = (row[r] < 0) ? row[r] - offset3 : row[r] + offset3;
101 int i, j, sum =
dim * connections_per_row;
108 for (i = 1; i <=
size; i++)
110 I[i] =
I[i-1] + connections_per_row;
111 for (j =
I[i-1]; j <
I[i]; j++) {
J[j] = -1; }
122 for (
int i = 0; i <
size; i++)
125 J[i] = partitioning[i];
134 for (
int i = 0; i <= nrows; i++)
144 for (k = i = 0; i <
size; i++)
146 j =
I[i],
I[i] = k, k += j;
156 for (
int i = 0; i < nc; i++)
165 for (
int i =
size; i > 0; i--)
179 for (
int i = 0, j = 0; i <
size; i++)
181 int end =
I[i] + connections_per_row;
183 for ( ; j < end; j++) {
J[j] = -1; }
192 j = (
I) ? (
I[
size]) : (0);
213 if ( i>=
size || i<0 )
219 for (k =
I[i]; k < end; k++)
235 MFEM_ASSERT(i >= 0 && i <
size,
"Row index " << i <<
" is out of range [0,"
247 for (
int r = 0; r <
size; r++)
249 std::sort(
J +
I[r],
J +
I[r+1]);
266 i<
size,
"Index out of bounds. i = " << i <<
" size " <<
size);
268 for (
int k =
I[i], end =
I[i+1]; k < end; k++)
281 MFEM_ABORT(
"Reached end of loop unexpectedly: (i,j) = (" << i <<
", " << j
289 int i, j, end, sum = 0, n = 0, newI = 0;
291 for (i=0; i<
I[
size]; i++)
303 for (i=0; i<
size; i++)
306 for (j=
I[i]; j<end; j++)
308 if (
J[j] == -1) {
break; }
318 MFEM_ASSERT(sum == n,
"sum = " << sum <<
", n = " << n);
327 int nnz = list.Size();
332 for (
int i = 0, k = 0; i <=
size; i++)
335 while (k < nnz && list[k].from == i)
345 int width = -1, nnz = (
size >= 0) ?
I[
size] : 0;
346 for (
int k = 0; k < nnz; k++)
348 if (
J[k] > width) { width =
J[k]; }
357 for (i = 0; i <
size; i++)
359 os <<
"[row " << i <<
"]\n";
360 for (j =
I[i]; j <
I[i+1]; j++)
362 os << setw(5) <<
J[j];
363 if ( !((j+1-
I[i]) % width) )
368 if ((j-
I[i]) % width)
379 for (i = 0; i <
size; i++)
381 for (j =
I[i]; j <
I[i+1]; j++)
383 os << i <<
" " <<
J[j] <<
" 1. \n";
394 for (
int i = 0; i <=
size; i++)
398 for (
int i = 0, nnz =
I[
size]; i < nnz; i++)
408 for (
int i = 0; i <=
size; i++)
414 for (
int j = 0; j < nnz; j++)
439 if (
size < 0 ||
I == NULL) {
return 0; }
445 const int *i_A = A.
GetI();
446 const int *j_A = A.
GetJ();
447 const int nrows_A = A.
Size();
448 const int ncols_A = (ncols_A_ < 0) ? A.
Width() : ncols_A_;
449 const int nnz_A = i_A[nrows_A];
453 int *i_At = At.
GetI();
454 int *j_At = At.
GetJ();
456 for (
int i = 0; i <= ncols_A; i++)
460 for (
int i = 0; i < nnz_A; i++)
464 for (
int i = 1; i < ncols_A; i++)
466 i_At[i+1] += i_At[i];
469 for (
int i = 0; i < nrows_A; i++)
471 for (
int j = i_A[i]; j < i_A[i+1]; j++)
473 j_At[i_At[j_A[j]]++] = i;
476 for (
int i = ncols_A; i > 0; i--)
492 At.
MakeI((ncols_A_ < 0) ? (A.
Max() + 1) : ncols_A_);
493 for (
int i = 0; i < A.
Size(); i++)
498 for (
int i = 0; i < A.
Size(); i++)
508 const int *i_A = A.
GetI();
509 const int *j_A = A.
GetJ();
510 const int *i_B = B.
GetI();
511 const int *j_B = B.
GetJ();
512 const int nrows_A = A.
Size();
513 const int nrows_B = B.
Size();
514 const int ncols_A = A.
Width();
515 const int ncols_B = B.
Width();
517 MFEM_VERIFY( ncols_A <= nrows_B,
"Table size mismatch: ncols_A = " << ncols_A
518 <<
", nrows_B = " << nrows_B);
522 for (i = 0; i < ncols_B; i++)
528 for (i = 0; i < nrows_A; i++)
530 for (j = i_A[i]; j < i_A[i+1]; j++)
533 for (l = i_B[k]; l < i_B[k+1]; l++)
536 if (B_marker[m] != i)
547 for (i = 0; i < ncols_B; i++)
555 for (i = 0; i < nrows_A; i++)
558 for (j = i_A[i]; j < i_A[i+1]; j++)
561 for (l = i_B[k]; l < i_B[k+1]; l++)
564 if (B_marker[m] != i)
614 Rows =
new Node*[nrows];
615 for (
int i = 0; i < nrows; i++)
623int DSTable::Push_(
int r,
int c)
625 MFEM_ASSERT(r >= 0 && r < NumRows,
626 "Row out of bounds: r = " << r <<
", NumRows = " << NumRows);
628 for (n = Rows[r]; n != NULL; n = n->Prev)
635#ifdef MFEM_USE_MEMALLOC
636 n = NodesMem.
Alloc ();
641 n->Index = NumEntries;
644 return (NumEntries++);
647int DSTable::Index(
int r,
int c)
const
649 MFEM_ASSERT( r>=0,
"Row index must be non-negative, not "<<r);
654 for (Node *n = Rows[r]; n != NULL; n = n->Prev)
666#ifdef MFEM_USE_MEMALLOC
669 for (
int i = 0; i < NumRows; i++)
671 Node *na, *nb = Rows[i];
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Assign(const T *)
Copy data from a pointer. 'Size()' elements are copied.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
void DeleteAll()
Delete the whole array.
STable(int dim, int connections_per_row=3)
Creates table with fixed number of connections.
int operator()(int i, int j) const
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
void Save(std::ostream &out) const
int size
The number of TYPE I elements.
const int * HostReadI() const
Array< int > J
The length of the J array is equal to the number of connections between TYPE I and TYPE II elements.
void AddConnections(int r, const int *c, int nc)
void PrintMatlab(std::ostream &out) const
void Load(std::istream &in)
int operator()(int i, int j) const
Returns index of the connection between element i of TYPE I and element j of TYPE II.
void SetSize(int dim, int connections_per_row)
Set the size and the number of connections for the table.
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
int Push(int i, int j)
Establish connection between element i and element j in the table.
void AddConnection(int r, int c)
Array< int > I
The length of the I array is 'size + 1',.
void Finalize()
Finalize the table initialization.
void Print(std::ostream &out=mfem::out, int width=4) const
Prints the table to the stream out.
void SetIJ(int *newI, int *newJ, int newsize=-1)
Replace the I and J arrays with the given newI and newJ arrays.
const int * HostReadJ() const
Table()
Creates an empty table.
int Size() const
Returns the number of TYPE I elements.
int Width() const
Returns the number of TYPE II elements (after Finalize() is called).
std::size_t MemoryUsage() const
void MakeFromList(int nrows, const Array< Connection > &list)
Create the table from a list of connections {(from, to)}, where 'from' is a TYPE I index and 'to' is ...
void Copy(Table ©) const
void AddAColumnInRow(int r)
void SortRows()
Sort the column (TYPE II) indices in each row.
void SetDims(int rows, int nnz)
Set the rows and the number of all connections for the table.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
void Swap(T &a, T &b)
Swap objects of type T. The operation is performed using the most specialized swap function from the ...