MFEM v4.8.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/** Data type Table. Table stores the connectivity of elements of TYPE I
41 to elements of TYPE II, for example, it may be Element-To-Face
42 connectivity table, etc. */
43class Table
44{
45protected:
46 /// size is the number of TYPE I elements.
47 int size;
48
49 /** Arrays for the connectivity information in the CSR storage.
50 I is of size "size+1", J is of size the number of connections
51 between TYPE I to TYPE II elements (actually stored I[size]). */
53
54public:
55 /// Creates an empty table
56 Table() { size = -1; }
57
58 /// Copy constructor
59 Table(const Table &);
60
61 /** Merge constructors
62 This is used to combine two or three tables into one table.*/
63 Table(const Table &table1,
64 const Table &table2, int offset2);
65 Table(const Table &table1,
66 const Table &table2, int offset2,
67 const Table &table3, int offset3);
68
69 /// Assignment operator: deep copy
70 Table& operator=(const Table &rhs);
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 /** Create a table with one entry per row with column indices given
80 by 'partitioning'. */
81 Table (int nrows, int *partitioning);
82
83 /// Next 7 methods are used together with the default constructor
84 void MakeI (int nrows);
85 void AddAColumnInRow (int r) { I[r]++; }
86 void AddColumnsInRow (int r, int ncol) { I[r] += ncol; }
87 void MakeJ();
88 void AddConnection (int r, int c) { J[I[r]++] = c; }
89 void AddConnections (int r, const int *c, int nc);
90 void ShiftUpI();
91
92 /// Set the size and the number of connections for the table.
93 void SetSize(int dim, int connections_per_row);
94
95 /** Set the rows and the number of all connections for the table.
96 Does NOT initialize the whole array I ! (I[0]=0 and I[rows]=nnz only) */
97 void SetDims(int rows, int nnz);
98
99 /// Returns the number of TYPE I elements.
100 inline int Size() const { return size; }
101
102 /** Returns the number of connections in the table. If Finalize() is
103 not called, it returns the number of possible connections established
104 by the used constructor. Otherwise, it is exactly the number of
105 established connections before calling Finalize(). */
106 inline int Size_of_connections() const { HostReadI(); return I[size]; }
107
108 /** Returns index of the connection between element i of TYPE I and
109 element j of TYPE II. If there is no connection between element i
110 and element j established in the table, then the return value is -1. */
111 int operator() (int i, int j) const;
112
113 /// Return row i in array row (the Table must be finalized)
114 void GetRow(int i, Array<int> &row) const;
115
116 int RowSize(int i) const { return I[i+1]-I[i]; }
117
118 const int *GetRow(int i) const { return J+I[i]; }
119 int *GetRow(int i) { return J+I[i]; }
120
121 int *GetI() { return I; }
122 int *GetJ() { return J; }
123 const int *GetI() const { return I; }
124 const int *GetJ() const { return J; }
125
126 Memory<int> &GetIMemory() { return I; }
127 Memory<int> &GetJMemory() { return J; }
128 const Memory<int> &GetIMemory() const { return I; }
129 const Memory<int> &GetJMemory() const { return J; }
130
131 const int *ReadI(bool on_dev = true) const
132 { return mfem::Read(I, I.Capacity(), on_dev); }
133 int *WriteI(bool on_dev = true)
134 { return mfem::Write(I, I.Capacity(), on_dev); }
135 int *ReadWriteI(bool on_dev = true)
136 { return mfem::ReadWrite(I, I.Capacity(), on_dev); }
137 const int *HostReadI() const
138 { return mfem::Read(I, I.Capacity(), false); }
140 { return mfem::Write(I, I.Capacity(), false); }
142 { return mfem::ReadWrite(I, I.Capacity(), false); }
143
144 const int *ReadJ(bool on_dev = true) const
145 { return mfem::Read(J, J.Capacity(), on_dev); }
146 int *WriteJ(bool on_dev = true)
147 { return mfem::Write(J, J.Capacity(), on_dev); }
148 int *ReadWriteJ(bool on_dev = true)
149 { return mfem::ReadWrite(J, J.Capacity(), on_dev); }
150 const int *HostReadJ() const
151 { return mfem::Read(J, J.Capacity(), false); }
153 { return mfem::Write(J, J.Capacity(), false); }
155 { return mfem::ReadWrite(J, J.Capacity(), false); }
156
157 /// @brief Sort the column (TYPE II) indices in each row.
158 void SortRows();
159
160 /// Replace the #I and #J arrays with the given @a newI and @a newJ arrays.
161 /** If @a newsize < 0, then the size of the Table is not modified. */
162 void SetIJ(int *newI, int *newJ, int newsize = -1);
163
164 /** Establish connection between element i and element j in the table.
165 The return value is the index of the connection. It returns -1 if it
166 fails to establish the connection. Possibilities are there is not
167 enough memory on row i to establish connection to j, an attempt to
168 establish new connection after calling Finalize(). */
169 int Push( int i, int j );
170
171 /** Finalize the table initialization. The function may be called
172 only once, after the table has been initialized, in order to compress
173 array J (by getting rid of -1's in array J). Calling this function
174 will "freeze" the table and function Push will work no more.
175 Note: The table is functional even without calling Finalize(). */
176 void Finalize();
177
178 /** Create the table from a list of connections {(from, to)}, where 'from'
179 is a TYPE I index and 'to' is a TYPE II index. The list is assumed to be
180 sorted and free of duplicities, i.e., you need to call Array::Sort and
181 Array::Unique before calling this method. */
182 void MakeFromList(int nrows, const Array<Connection> &list);
183
184 /// Returns the number of TYPE II elements (after Finalize() is called).
185 int Width() const;
186
187 /// Call this if data has been stolen.
188 void LoseData() { size = -1; I.Reset(); J.Reset(); }
189
190 /// Prints the table to stream out.
191 void Print(std::ostream & out = mfem::out, int width = 4) const;
192 void PrintMatlab(std::ostream & out) const;
193
194 void Save(std::ostream &out) const;
195 void Load(std::istream &in);
196
197 void Copy(Table & copy) const;
198 void Swap(Table & other);
199
200 void Clear();
201
202 std::size_t MemoryUsage() const;
203
204 /// Destroys Table.
205 ~Table();
206};
207
208/// Specialization of the template function Swap<> for class Table
209template <> inline void Swap<Table>(Table &a, Table &b)
210{
211 a.Swap(b);
212}
213
214/// Transpose a Table
215void Transpose (const Table &A, Table &At, int ncols_A_ = -1);
216Table * Transpose (const Table &A);
217
218/// @brief Transpose an Array<int>.
219///
220/// The array @a A represents a table where each row @a i has exactly one
221/// connection to the column (TYPE II) index specified by @a A[i].
222///
223/// @note The column (TYPE II) indices in each row of @a At will be sorted.
224void Transpose(const Array<int> &A, Table &At, int ncols_A_ = -1);
225
226/// C = A * B (as boolean matrices)
227void Mult (const Table &A, const Table &B, Table &C);
228Table * Mult (const Table &A, const Table &B);
229
230
231/** Data type STable. STable is similar to Table, but it's for symmetric
232 connectivity, i.e. TYPE I is equivalent to TYPE II. In the first
233 dimension we put the elements with smaller index. */
234class STable : public Table
235{
236public:
237 /// Creates table with fixed number of connections.
238 STable (int dim, int connections_per_row = 3);
239
240 /** Returns index of the connection between element i of TYPE I and
241 element j of TYPE II. If there is no connection between element i
242 and element j established in the table, then the return value is -1. */
243 int operator() (int i, int j) const;
244
245 /** Establish connection between element i and element j in the table.
246 The return value is the index of the connection. It returns -1 if it
247 fails to establish the connection. Possibilities are there is not
248 enough memory on row i to establish connection to j, an attempt to
249 establish new connection after calling Finalize(). */
250 int Push( int i, int j );
251
252 /// Destroys STable.
254};
255
256
258{
259private:
260 class Node
261 {
262 public:
263 Node *Prev;
264 int Column, Index;
265 };
266
267 int NumRows, NumEntries;
268 Node **Rows;
269#ifdef MFEM_USE_MEMALLOC
270 MemAlloc <Node, 1024> NodesMem;
271#endif
272
273 int Push_(int r, int c);
274 int Index(int r, int c) const;
275
276public:
277 DSTable(int nrows);
278 int NumberOfRows() const { return (NumRows); }
279 int NumberOfEntries() const { return (NumEntries); }
280 int Push(int a, int b)
281 { return ((a <= b) ? Push_(a, b) : Push_(b, a)); }
282 int operator()(int a, int b) const
283 { return ((a <= b) ? Index(a, b) : Index(b, a)); }
284 ~DSTable();
285
287 {
288 private:
289 Node *n;
290 public:
291 RowIterator (const DSTable &t, int r) { n = t.Rows[r]; }
292 int operator!() { return (n != NULL); }
293 void operator++() { n = n->Prev; }
294 int Column() { return (n->Column); }
295 int Index() { return (n->Index); }
296 void SetIndex(int new_idx) { n->Index = new_idx; }
297 };
298};
299
300}
301
302#endif
RowIterator(const DSTable &t, int r)
Definition table.hpp:291
void SetIndex(int new_idx)
Definition table.hpp:296
int NumberOfEntries() const
Definition table.hpp:279
int NumberOfRows() const
Definition table.hpp:278
int Push(int a, int b)
Definition table.hpp:280
DSTable(int nrows)
Definition table.cpp:655
int operator()(int a, int b) const
Definition table.hpp:282
Class used by MFEM to store pointers to host and/or device memory.
int Capacity() const
Return the size of the allocated memory.
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
int Push(int i, int j)
Definition table.cpp:642
STable(int dim, int connections_per_row=3)
Creates table with fixed number of connections.
Definition table.cpp:626
~STable()
Destroys STable.
Definition table.hpp:253
int operator()(int i, int j) const
Definition table.cpp:630
Table & operator=(const Table &rhs)
Assignment operator: deep copy.
Definition table.cpp:112
void Save(std::ostream &out) const
Definition table.cpp:420
int * HostWriteJ()
Definition table.hpp:152
int * HostWriteI()
Definition table.hpp:139
void LoseData()
Call this if data has been stolen.
Definition table.hpp:188
int size
size is the number of TYPE I elements.
Definition table.hpp:47
const int * GetRow(int i) const
Definition table.hpp:118
int * ReadWriteI(bool on_dev=true)
Definition table.hpp:135
const int * HostReadI() const
Definition table.hpp:137
~Table()
Destroys Table.
Definition table.cpp:480
const int * GetI() const
Definition table.hpp:123
int * GetJ()
Definition table.hpp:122
const int * ReadJ(bool on_dev=true) const
Definition table.hpp:144
Table(int nrows, Array< Connection > &list)
Definition table.hpp:76
void AddConnections(int r, const int *c, int nc)
Definition table.cpp:176
void PrintMatlab(std::ostream &out) const
Definition table.cpp:405
void Swap(Table &other)
Definition table.cpp:467
int RowSize(int i) const
Definition table.hpp:116
void Load(std::istream &in)
Definition table.cpp:434
int operator()(int i, int j) const
Definition table.cpp:237
void ShiftUpI()
Definition table.cpp:187
void Clear()
Definition table.cpp:453
void SetSize(int dim, int connections_per_row)
Set the size and the number of connections for the table.
Definition table.cpp:196
const Memory< int > & GetJMemory() const
Definition table.hpp:129
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
Definition table.cpp:259
const Memory< int > & GetIMemory() const
Definition table.hpp:128
int Push(int i, int j)
Definition table.cpp:291
void AddConnection(int r, int c)
Definition table.hpp:88
void Finalize()
Definition table.cpp:315
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
Definition table.cpp:153
void Print(std::ostream &out=mfem::out, int width=4) const
Prints the table to stream out.
Definition table.cpp:383
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:279
int * GetRow(int i)
Definition table.hpp:119
const int * HostReadJ() const
Definition table.hpp:150
Table()
Creates an empty table.
Definition table.hpp:56
const int * GetJ() const
Definition table.hpp:124
int Size() const
Returns the number of TYPE I elements.
Definition table.hpp:100
int Width() const
Returns the number of TYPE II elements (after Finalize() is called).
Definition table.cpp:373
const int * ReadI(bool on_dev=true) const
Definition table.hpp:131
std::size_t MemoryUsage() const
Definition table.cpp:474
int Size_of_connections() const
Definition table.hpp:106
void AddColumnsInRow(int r, int ncol)
Definition table.hpp:86
void MakeFromList(int nrows, const Array< Connection > &list)
Definition table.cpp:352
void Copy(Table &copy) const
Definition table.cpp:462
void MakeJ()
Definition table.cpp:163
Memory< int > J
Definition table.hpp:52
int * HostReadWriteI()
Definition table.hpp:141
Memory< int > I
Definition table.hpp:52
int * WriteI(bool on_dev=true)
Definition table.hpp:133
Memory< int > & GetJMemory()
Definition table.hpp:127
int * GetI()
Definition table.hpp:121
void AddAColumnInRow(int r)
Definition table.hpp:85
void SortRows()
Sort the column (TYPE II) indices in each row.
Definition table.cpp:271
int * WriteJ(bool on_dev=true)
Definition table.hpp:146
int * ReadWriteJ(bool on_dev=true)
Definition table.hpp:148
void SetDims(int rows, int nnz)
Definition table.cpp:212
Memory< int > & GetIMemory()
Definition table.hpp:126
int * HostReadWriteJ()
Definition table.hpp:154
int dim
Definition ex24.cpp:53
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
Definition device.hpp:341
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:548
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
Definition device.hpp:358
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:486
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device's DeviceMemoryClass,...
Definition device.hpp:375
void Swap< Table >(Table &a, Table &b)
Specialization of the template function Swap<> for class Table.
Definition table.hpp:209
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