MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
table.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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 /// Assignment operator: deep copy
62 Table& operator=(const Table &rhs);
63
64 /// Create a table with an upper limit for the number of connections.
65 explicit Table (int dim, int connections_per_row = 3);
66
67 /** Create a table from a list of connections, see MakeFromList(). */
68 Table(int nrows, Array<Connection> &list) : size(-1)
69 { MakeFromList(nrows, list); }
70
71 /** Create a table with one entry per row with column indices given
72 by 'partitioning'. */
73 Table (int nrows, int *partitioning);
74
75 /// Next 7 methods are used together with the default constructor
76 void MakeI (int nrows);
77 void AddAColumnInRow (int r) { I[r]++; }
78 void AddColumnsInRow (int r, int ncol) { I[r] += ncol; }
79 void MakeJ();
80 void AddConnection (int r, int c) { J[I[r]++] = c; }
81 void AddConnections (int r, const int *c, int nc);
82 void ShiftUpI();
83
84 /// Set the size and the number of connections for the table.
85 void SetSize(int dim, int connections_per_row);
86
87 /** Set the rows and the number of all connections for the table.
88 Does NOT initialize the whole array I ! (I[0]=0 and I[rows]=nnz only) */
89 void SetDims(int rows, int nnz);
90
91 /// Returns the number of TYPE I elements.
92 inline int Size() const { return size; }
93
94 /** Returns the number of connections in the table. If Finalize() is
95 not called, it returns the number of possible connections established
96 by the used constructor. Otherwise, it is exactly the number of
97 established connections before calling Finalize(). */
98 inline int Size_of_connections() const { HostReadI(); return I[size]; }
99
100 /** Returns index of the connection between element i of TYPE I and
101 element j of TYPE II. If there is no connection between element i
102 and element j established in the table, then the return value is -1. */
103 int operator() (int i, int j) const;
104
105 /// Return row i in array row (the Table must be finalized)
106 void GetRow(int i, Array<int> &row) const;
107
108 int RowSize(int i) const { return I[i+1]-I[i]; }
109
110 const int *GetRow(int i) const { return J+I[i]; }
111 int *GetRow(int i) { return J+I[i]; }
112
113 int *GetI() { return I; }
114 int *GetJ() { return J; }
115 const int *GetI() const { return I; }
116 const int *GetJ() const { return J; }
117
118 Memory<int> &GetIMemory() { return I; }
119 Memory<int> &GetJMemory() { return J; }
120 const Memory<int> &GetIMemory() const { return I; }
121 const Memory<int> &GetJMemory() const { return J; }
122
123 const int *ReadI(bool on_dev = true) const
124 { return mfem::Read(I, I.Capacity(), on_dev); }
125 int *WriteI(bool on_dev = true)
126 { return mfem::Write(I, I.Capacity(), on_dev); }
127 int *ReadWriteI(bool on_dev = true)
128 { return mfem::ReadWrite(I, I.Capacity(), on_dev); }
129 const int *HostReadI() const
130 { return mfem::Read(I, I.Capacity(), false); }
132 { return mfem::Write(I, I.Capacity(), false); }
134 { return mfem::ReadWrite(I, I.Capacity(), false); }
135
136 const int *ReadJ(bool on_dev = true) const
137 { return mfem::Read(J, J.Capacity(), on_dev); }
138 int *WriteJ(bool on_dev = true)
139 { return mfem::Write(J, J.Capacity(), on_dev); }
140 int *ReadWriteJ(bool on_dev = true)
141 { return mfem::ReadWrite(J, J.Capacity(), on_dev); }
142 const int *HostReadJ() const
143 { return mfem::Read(J, J.Capacity(), false); }
145 { return mfem::Write(J, J.Capacity(), false); }
147 { return mfem::ReadWrite(J, J.Capacity(), false); }
148
149 /// @brief Sort the column (TYPE II) indices in each row.
150 void SortRows();
151
152 /// Replace the #I and #J arrays with the given @a newI and @a newJ arrays.
153 /** If @a newsize < 0, then the size of the Table is not modified. */
154 void SetIJ(int *newI, int *newJ, int newsize = -1);
155
156 /** Establish connection between element i and element j in the table.
157 The return value is the index of the connection. It returns -1 if it
158 fails to establish the connection. Possibilities are there is not
159 enough memory on row i to establish connection to j, an attempt to
160 establish new connection after calling Finalize(). */
161 int Push( int i, int j );
162
163 /** Finalize the table initialization. The function may be called
164 only once, after the table has been initialized, in order to compress
165 array J (by getting rid of -1's in array J). Calling this function
166 will "freeze" the table and function Push will work no more.
167 Note: The table is functional even without calling Finalize(). */
168 void Finalize();
169
170 /** Create the table from a list of connections {(from, to)}, where 'from'
171 is a TYPE I index and 'to' is a TYPE II index. The list is assumed to be
172 sorted and free of duplicities, i.e., you need to call Array::Sort and
173 Array::Unique before calling this method. */
174 void MakeFromList(int nrows, const Array<Connection> &list);
175
176 /// Returns the number of TYPE II elements (after Finalize() is called).
177 int Width() const;
178
179 /// Call this if data has been stolen.
180 void LoseData() { size = -1; I.Reset(); J.Reset(); }
181
182 /// Prints the table to stream out.
183 void Print(std::ostream & out = mfem::out, int width = 4) const;
184 void PrintMatlab(std::ostream & out) const;
185
186 void Save(std::ostream &out) const;
187 void Load(std::istream &in);
188
189 void Copy(Table & copy) const;
190 void Swap(Table & other);
191
192 void Clear();
193
194 std::size_t MemoryUsage() const;
195
196 /// Destroys Table.
197 ~Table();
198};
199
200/// Specialization of the template function Swap<> for class Table
201template <> inline void Swap<Table>(Table &a, Table &b)
202{
203 a.Swap(b);
204}
205
206/// Transpose a Table
207void Transpose (const Table &A, Table &At, int ncols_A_ = -1);
208Table * Transpose (const Table &A);
209
210/// @brief Transpose an Array<int>.
211///
212/// The array @a A represents a table where each row @a i has exactly one
213/// connection to the column (TYPE II) index specified by @a A[i].
214///
215/// @note The column (TYPE II) indices in each row of @a At will be sorted.
216void Transpose(const Array<int> &A, Table &At, int ncols_A_ = -1);
217
218/// C = A * B (as boolean matrices)
219void Mult (const Table &A, const Table &B, Table &C);
220Table * Mult (const Table &A, const Table &B);
221
222
223/** Data type STable. STable is similar to Table, but it's for symmetric
224 connectivity, i.e. TYPE I is equivalent to TYPE II. In the first
225 dimension we put the elements with smaller index. */
226class STable : public Table
227{
228public:
229 /// Creates table with fixed number of connections.
230 STable (int dim, int connections_per_row = 3);
231
232 /** Returns index of the connection between element i of TYPE I and
233 element j of TYPE II. If there is no connection between element i
234 and element j established in the table, then the return value is -1. */
235 int operator() (int i, int j) const;
236
237 /** Establish connection between element i and element j in the table.
238 The return value is the index of the connection. It returns -1 if it
239 fails to establish the connection. Possibilities are there is not
240 enough memory on row i to establish connection to j, an attempt to
241 establish new connection after calling Finalize(). */
242 int Push( int i, int j );
243
244 /// Destroys STable.
246};
247
248
250{
251private:
252 class Node
253 {
254 public:
255 Node *Prev;
256 int Column, Index;
257 };
258
259 int NumRows, NumEntries;
260 Node **Rows;
261#ifdef MFEM_USE_MEMALLOC
262 MemAlloc <Node, 1024> NodesMem;
263#endif
264
265 int Push_(int r, int c);
266 int Index(int r, int c) const;
267
268public:
269 DSTable(int nrows);
270 int NumberOfRows() const { return (NumRows); }
271 int NumberOfEntries() const { return (NumEntries); }
272 int Push(int a, int b)
273 { return ((a <= b) ? Push_(a, b) : Push_(b, a)); }
274 int operator()(int a, int b) const
275 { return ((a <= b) ? Index(a, b) : Index(b, a)); }
276 ~DSTable();
277
279 {
280 private:
281 Node *n;
282 public:
283 RowIterator (const DSTable &t, int r) { n = t.Rows[r]; }
284 int operator!() { return (n != NULL); }
285 void operator++() { n = n->Prev; }
286 int Column() { return (n->Column); }
287 int Index() { return (n->Index); }
288 void SetIndex(int new_idx) { n->Index = new_idx; }
289 };
290};
291
292}
293
294#endif
RowIterator(const DSTable &t, int r)
Definition table.hpp:283
void SetIndex(int new_idx)
Definition table.hpp:288
int NumberOfEntries() const
Definition table.hpp:271
int NumberOfRows() const
Definition table.hpp:270
int Push(int a, int b)
Definition table.hpp:272
DSTable(int nrows)
Definition table.cpp:583
int operator()(int a, int b) const
Definition table.hpp:274
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:570
STable(int dim, int connections_per_row=3)
Creates table with fixed number of connections.
Definition table.cpp:554
~STable()
Destroys STable.
Definition table.hpp:245
int operator()(int i, int j) const
Definition table.cpp:558
Table & operator=(const Table &rhs)
Assignment operator: deep copy.
Definition table.cpp:40
void Save(std::ostream &out) const
Definition table.cpp:348
int * HostWriteJ()
Definition table.hpp:144
int * HostWriteI()
Definition table.hpp:131
void LoseData()
Call this if data has been stolen.
Definition table.hpp:180
int size
size is the number of TYPE I elements.
Definition table.hpp:47
const int * GetRow(int i) const
Definition table.hpp:110
int * ReadWriteI(bool on_dev=true)
Definition table.hpp:127
const int * HostReadI() const
Definition table.hpp:129
~Table()
Destroys Table.
Definition table.cpp:408
const int * GetI() const
Definition table.hpp:115
int * GetJ()
Definition table.hpp:114
const int * ReadJ(bool on_dev=true) const
Definition table.hpp:136
Table(int nrows, Array< Connection > &list)
Definition table.hpp:68
void AddConnections(int r, const int *c, int nc)
Definition table.cpp:104
void PrintMatlab(std::ostream &out) const
Definition table.cpp:333
void Swap(Table &other)
Definition table.cpp:395
int RowSize(int i) const
Definition table.hpp:108
void Load(std::istream &in)
Definition table.cpp:362
int operator()(int i, int j) const
Definition table.cpp:165
void ShiftUpI()
Definition table.cpp:115
void Clear()
Definition table.cpp:381
void SetSize(int dim, int connections_per_row)
Set the size and the number of connections for the table.
Definition table.cpp:124
const Memory< int > & GetJMemory() const
Definition table.hpp:121
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
Definition table.cpp:187
const Memory< int > & GetIMemory() const
Definition table.hpp:120
int Push(int i, int j)
Definition table.cpp:219
void AddConnection(int r, int c)
Definition table.hpp:80
void Finalize()
Definition table.cpp:243
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
Definition table.cpp:81
void Print(std::ostream &out=mfem::out, int width=4) const
Prints the table to stream out.
Definition table.cpp:311
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:207
int * GetRow(int i)
Definition table.hpp:111
const int * HostReadJ() const
Definition table.hpp:142
Table()
Creates an empty table.
Definition table.hpp:56
const int * GetJ() const
Definition table.hpp:116
int Size() const
Returns the number of TYPE I elements.
Definition table.hpp:92
int Width() const
Returns the number of TYPE II elements (after Finalize() is called).
Definition table.cpp:301
const int * ReadI(bool on_dev=true) const
Definition table.hpp:123
std::size_t MemoryUsage() const
Definition table.cpp:402
int Size_of_connections() const
Definition table.hpp:98
void AddColumnsInRow(int r, int ncol)
Definition table.hpp:78
void MakeFromList(int nrows, const Array< Connection > &list)
Definition table.cpp:280
void Copy(Table &copy) const
Definition table.cpp:390
void MakeJ()
Definition table.cpp:91
Memory< int > J
Definition table.hpp:52
int * HostReadWriteI()
Definition table.hpp:133
Memory< int > I
Definition table.hpp:52
int * WriteI(bool on_dev=true)
Definition table.hpp:125
Memory< int > & GetJMemory()
Definition table.hpp:119
int * GetI()
Definition table.hpp:113
void AddAColumnInRow(int r)
Definition table.hpp:77
void SortRows()
Sort the column (TYPE II) indices in each row.
Definition table.cpp:199
int * WriteJ(bool on_dev=true)
Definition table.hpp:138
int * ReadWriteJ(bool on_dev=true)
Definition table.hpp:140
void SetDims(int rows, int nnz)
Definition table.cpp:140
Memory< int > & GetIMemory()
Definition table.hpp:118
int * HostReadWriteJ()
Definition table.hpp:146
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:320
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:476
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:337
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:414
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:354
void Swap< Table >(Table &a, Table &b)
Specialization of the template function Swap<> for class Table.
Definition table.hpp:201
RefCoord t[3]
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