MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
table.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_TABLE
13#define MFEM_TABLE
14
15// Data types for Table.
16
17#include "mem_alloc.hpp"
18#include "array.hpp"
19#include "globals.hpp"
20#include <ostream>
21#include <istream>
22
23namespace mfem
24{
25
26/// Helper struct for defining a connectivity table, see Table::MakeFromList.
28{
29 int from, to;
30 Connection() = default;
31 Connection(int from, int to) : from(from), to(to) { }
32
33 bool operator==(const Connection &rhs) const
34 { return (from == rhs.from) && (to == rhs.to); }
35 bool operator<(const Connection &rhs) const
36 { return (from == rhs.from) ? (to < rhs.to) : (from < rhs.from); }
37};
38
39
40/** @brief Table stores the connectivity of elements of TYPE I to elements of
41 TYPE II. For example, it may be the element-to-face connectivity table. */
42class Table
43{
44protected:
45 int size; ///< The number of TYPE I elements.
46
47 /// @name Arrays for the connectivity information in the CSR storage.
48 /// @{
49
50 /// The length of the I array is 'size + 1',
52
53 /// @brief The length of the J array is equal to the number of connections
54 /// between TYPE I and TYPE II elements.
56
57 /// @}
58
59public:
60 /// Creates an empty table
61 Table() { size = -1; }
62
63 /// Merge constructor: combine two tables into one table.
64 Table(const Table &table1,
65 const Table &table2, int offset2);
66
67 /// Merge constructor: combine three tables into one table.
68 Table(const Table &table1,
69 const Table &table2, int offset2,
70 const Table &table3, int offset3);
71
72 /// Create a table with an upper limit for the number of connections.
73 explicit Table(int dim, int connections_per_row = 3);
74
75 /// Create a table from a list of connections, see MakeFromList().
76 Table(int nrows, Array<Connection> &list) : size(-1)
77 { MakeFromList(nrows, list); }
78
79 /// @brief Create a table with one entry per row with column indices given by
80 /// @a partitioning.
81 Table(int nrows, int *partitioning);
82
83 /// @name Used together with the default constructor
84 /// @{
85 void MakeI(int nrows);
86 void AddAColumnInRow(int r) { I[r]++; }
87 void AddColumnsInRow(int r, int ncol) { I[r] += ncol; }
88 void MakeJ();
89 void AddConnection(int r, int c) { J[I[r]++] = c; }
90 void AddConnections(int r, const int *c, int nc);
91 void ShiftUpI();
92 /// @}
93
94 /// Set the size and the number of connections for the table.
95 void SetSize(int dim, int connections_per_row);
96
97 /// @brief Set the rows and the number of all connections for the table.
98 ///
99 /// Does NOT initialize the whole array I ! (I[0]=0 and I[rows]=nnz only)
100 void SetDims(int rows, int nnz);
101
102 /// Returns the number of TYPE I elements.
103 inline int Size() const { return size; }
104
105 /// @brief Returns the number of connections in the table.
106 ///
107 /// If Finalize() is not called, it returns the number of possible
108 /// connections established by the used constructor. Otherwise, it is exactly
109 /// the number of established connections after calling Finalize(). */
110 inline int Size_of_connections() const { return J.Size(); }
111
112 /// @brief Returns index of the connection between element i of TYPE I and
113 /// element j of TYPE II.
114 ///
115 /// If there is no connection between element i and element j established in
116 /// the table, then the return value is -1.
117 int operator() (int i, int j) const;
118
119 /// Return row i in array row (the Table must be finalized)
120 void GetRow(int i, Array<int> &row) const;
121
122 int RowSize(int i) const { return I[i+1] - I[i]; }
123
124 const int *GetRow(int i) const { return J.GetMemory() + I[i]; }
125 int *GetRow(int i) { return J.GetMemory() + I[i]; }
126
127 int *GetI() { return I.GetData(); }
128 int *GetJ() { return J.GetData(); }
129 const int *GetI() const { return I.GetData(); }
130 const int *GetJ() const { return J.GetData(); }
131
134 const Memory<int> &GetIMemory() const { return I.GetMemory(); }
135 const Memory<int> &GetJMemory() const { return J.GetMemory(); }
136
137 const int *ReadI(bool on_dev = true) const { return I.Read(on_dev); }
138 int *WriteI(bool on_dev = true) { return I.Write(on_dev); }
139 int *ReadWriteI(bool on_dev = true) { return I.ReadWrite(on_dev); }
140 const int *HostReadI() const { return I.HostRead(); }
141 int *HostWriteI() { return I.HostWrite(); }
142 int *HostReadWriteI() { return I.HostReadWrite(); }
143
144 const int *ReadJ(bool on_dev = true) const { return J.Read(on_dev); }
145 int *WriteJ(bool on_dev = true) { return J.Write(on_dev); }
146 int *ReadWriteJ(bool on_dev = true) { return J.ReadWrite(on_dev); }
147 const int *HostReadJ() const { return J.HostRead(); }
148 int *HostWriteJ() { return J.HostWrite(); }
149 int *ReadWriteJ() { return J.HostReadWrite(); }
150
151 /// Sort the column (TYPE II) indices in each row.
152 void SortRows();
153
154 /// Replace the #I and #J arrays with the given @a newI and @a newJ arrays.
155 /** If @a newsize < 0, then the size of the Table is not modified. */
156 void SetIJ(int *newI, int *newJ, int newsize = -1);
157
158 /// Establish connection between element i and element j in the table.
159 /** The return value is the index of the connection. It returns -1 if it
160 fails to establish the connection. Possibilities are there is not enough
161 memory on row i to establish connection to j, an attempt to establish new
162 connection after calling Finalize(). */
163 int Push( int i, int j );
164
165 /// Finalize the table initialization.
166 /** The function may be called only once, after the table has been
167 initialized, in order to compress array J (by getting rid of -1's in
168 array J). Calling this function will "freeze" the table and function Push
169 will work no more. Note: The table is functional even without calling
170 Finalize(). */
171 void Finalize();
172
173 /// @brief Create the table from a list of connections {(from, to)}, where
174 /// 'from' is a TYPE I index and 'to' is a TYPE II index.
175 ///
176 /// The list is assumed to be sorted and free of duplicities, i.e., you need
177 /// to call Array::Sort and Array::Unique before calling this method. */
178 void MakeFromList(int nrows, const Array<Connection> &list);
179
180 /// Returns the number of TYPE II elements (after Finalize() is called).
181 int Width() const;
182
183 /// Releases ownership of and null-ifies the data.
184 void LoseData() { size = -1; I.LoseData(); J.LoseData(); }
185
186 /// Prints the table to the stream @a out.
187 void Print(std::ostream & out = mfem::out, int width = 4) const;
188 void PrintMatlab(std::ostream & out) const;
189
190 void Save(std::ostream &out) const;
191 void Load(std::istream &in);
192
193 void Copy(Table & copy) const;
194 void Swap(Table & other);
195
196 void Clear();
197
198 std::size_t MemoryUsage() const;
199};
200
201/// Transpose a Table
202void Transpose (const Table &A, Table &At, int ncols_A_ = -1);
203Table * Transpose (const Table &A);
204
205/// @brief Transpose an Array<int>.
206///
207/// The array @a A represents a table where each row @a i has exactly one
208/// connection to the column (TYPE II) index specified by @a A[i].
209///
210/// @note The column (TYPE II) indices in each row of @a At will be sorted.
211void Transpose(const Array<int> &A, Table &At, int ncols_A_ = -1);
212
213/// C = A * B (as boolean matrices)
214void Mult (const Table &A, const Table &B, Table &C);
215Table * Mult (const Table &A, const Table &B);
216
217
218/** Data type STable. STable is similar to Table, but it's for symmetric
219 connectivity, i.e. TYPE I is equivalent to TYPE II. In the first
220 dimension we put the elements with smaller index. */
221class STable : public Table
222{
223public:
224 /// Creates table with fixed number of connections.
225 STable (int dim, int connections_per_row = 3);
226
227 /** Returns index of the connection between element i of TYPE I and
228 element j of TYPE II. If there is no connection between element i
229 and element j established in the table, then the return value is -1. */
230 int operator() (int i, int j) const;
231
232 /** Establish connection between element i and element j in the table.
233 The return value is the index of the connection. It returns -1 if it
234 fails to establish the connection. Possibilities are there is not
235 enough memory on row i to establish connection to j, an attempt to
236 establish new connection after calling Finalize(). */
237 int Push( int i, int j );
238
239 /// Destroys STable.
241};
242
243
245{
246private:
247 class Node
248 {
249 public:
250 Node *Prev;
251 int Column, Index;
252 };
253
254 int NumRows, NumEntries;
255 Node **Rows;
256#ifdef MFEM_USE_MEMALLOC
257 MemAlloc <Node, 1024> NodesMem;
258#endif
259
260 int Push_(int r, int c);
261 int Index(int r, int c) const;
262
263public:
264 DSTable(int nrows);
265 int NumberOfRows() const { return (NumRows); }
266 int NumberOfEntries() const { return (NumEntries); }
267 int Push(int a, int b)
268 { return ((a <= b) ? Push_(a, b) : Push_(b, a)); }
269 int operator()(int a, int b) const
270 { return ((a <= b) ? Index(a, b) : Index(b, a)); }
271 ~DSTable();
272
274 {
275 private:
276 Node *n;
277 public:
278 RowIterator (const DSTable &t, int r) { n = t.Rows[r]; }
279 int operator!() { return (n != NULL); }
280 void operator++() { n = n->Prev; }
281 int Column() { return (n->Column); }
282 int Index() { return (n->Index); }
283 void SetIndex(int new_idx) { n->Index = new_idx; }
284 };
285};
286
287}
288
289#endif
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
Definition array.hpp:145
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
Definition array.hpp:385
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:397
void LoseData()
NULL-ifies the data.
Definition array.hpp:160
int Size() const
Return the logical size of the array.
Definition array.hpp:166
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:389
T * GetData()
Returns the data.
Definition array.hpp:140
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:381
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
Definition array.hpp:401
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
Definition array.hpp:393
RowIterator(const DSTable &t, int r)
Definition table.hpp:278
void SetIndex(int new_idx)
Definition table.hpp:283
int NumberOfEntries() const
Definition table.hpp:266
int NumberOfRows() const
Definition table.hpp:265
int Push(int a, int b)
Definition table.hpp:267
DSTable(int nrows)
Definition table.cpp:612
int operator()(int a, int b) const
Definition table.hpp:269
Class used by MFEM to store pointers to host and/or device memory.
int Push(int i, int j)
Definition table.cpp:599
STable(int dim, int connections_per_row=3)
Creates table with fixed number of connections.
Definition table.cpp:583
~STable()
Destroys STable.
Definition table.hpp:240
int operator()(int i, int j) const
Definition table.cpp:587
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
Definition table.hpp:43
void Save(std::ostream &out) const
Definition table.cpp:390
int * HostWriteJ()
Definition table.hpp:148
int * HostWriteI()
Definition table.hpp:141
void LoseData()
Releases ownership of and null-ifies the data.
Definition table.hpp:184
int size
The number of TYPE I elements.
Definition table.hpp:45
const int * GetRow(int i) const
Definition table.hpp:124
int * ReadWriteI(bool on_dev=true)
Definition table.hpp:139
const int * HostReadI() const
Definition table.hpp:140
const int * GetI() const
Definition table.hpp:129
int * GetJ()
Definition table.hpp:128
const int * ReadJ(bool on_dev=true) const
Definition table.hpp:144
Table(int nrows, Array< Connection > &list)
Create a table from a list of connections, see MakeFromList().
Definition table.hpp:76
Array< int > J
The length of the J array is equal to the number of connections between TYPE I and TYPE II elements.
Definition table.hpp:55
void AddConnections(int r, const int *c, int nc)
Definition table.cpp:152
void PrintMatlab(std::ostream &out) const
Definition table.cpp:375
void Swap(Table &other)
Definition table.cpp:432
int RowSize(int i) const
Definition table.hpp:122
void Load(std::istream &in)
Definition table.cpp:404
int operator()(int i, int j) const
Returns index of the connection between element i of TYPE I and element j of TYPE II.
Definition table.cpp:211
void ShiftUpI()
Definition table.cpp:163
void Clear()
Definition table.cpp:420
void SetSize(int dim, int connections_per_row)
Set the size and the number of connections for the table.
Definition table.cpp:172
const Memory< int > & GetJMemory() const
Definition table.hpp:135
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
Definition table.cpp:233
const Memory< int > & GetIMemory() const
Definition table.hpp:134
int Push(int i, int j)
Establish connection between element i and element j in the table.
Definition table.cpp:263
void AddConnection(int r, int c)
Definition table.hpp:89
Array< int > I
The length of the I array is 'size + 1',.
Definition table.hpp:51
void Finalize()
Finalize the table initialization.
Definition table.cpp:287
void MakeI(int nrows)
Definition table.cpp:130
void Print(std::ostream &out=mfem::out, int width=4) const
Prints the table to the stream out.
Definition table.cpp:353
void SetIJ(int *newI, int *newJ, int newsize=-1)
Replace the I and J arrays with the given newI and newJ arrays.
Definition table.cpp:253
int * GetRow(int i)
Definition table.hpp:125
int * ReadWriteJ()
Definition table.hpp:149
const int * HostReadJ() const
Definition table.hpp:147
Table()
Creates an empty table.
Definition table.hpp:61
const int * GetJ() const
Definition table.hpp:130
int Size() const
Returns the number of TYPE I elements.
Definition table.hpp:103
int Width() const
Returns the number of TYPE II elements (after Finalize() is called).
Definition table.cpp:343
const int * ReadI(bool on_dev=true) const
Definition table.hpp:137
std::size_t MemoryUsage() const
Definition table.cpp:437
int Size_of_connections() const
Returns the number of connections in the table.
Definition table.hpp:110
void AddColumnsInRow(int r, int ncol)
Definition table.hpp:87
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 ...
Definition table.cpp:322
void Copy(Table &copy) const
Definition table.cpp:427
void MakeJ()
Definition table.cpp:140
int * HostReadWriteI()
Definition table.hpp:142
int * WriteI(bool on_dev=true)
Definition table.hpp:138
Memory< int > & GetJMemory()
Definition table.hpp:133
int * GetI()
Definition table.hpp:127
void AddAColumnInRow(int r)
Definition table.hpp:86
void SortRows()
Sort the column (TYPE II) indices in each row.
Definition table.cpp:245
int * WriteJ(bool on_dev=true)
Definition table.hpp:145
int * ReadWriteJ(bool on_dev=true)
Definition table.hpp:146
void SetDims(int rows, int nnz)
Set the rows and the number of all connections for the table.
Definition table.cpp:188
Memory< int > & GetIMemory()
Definition table.hpp:132
int dim
Definition ex24.cpp:53
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:505
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
Definition table.cpp:443
Helper struct for defining a connectivity table, see Table::MakeFromList.
Definition table.hpp:28
bool operator==(const Connection &rhs) const
Definition table.hpp:33
bool operator<(const Connection &rhs) const
Definition table.hpp:35
Connection(int from, int to)
Definition table.hpp:31
Connection()=default