BELFEM 0.9.3
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
cl_Mesh_Basis.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California,
4 * through Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
12#ifndef BELFEM_CL_MESH_BASIS_HPP
13#define BELFEM_CL_MESH_BASIS_HPP
14
15#include <limits>
16
17#include "typedefs.hpp"
18#include "cl_Graph_Vertex.hpp"
19#include "Mesh_Enums.hpp"
20#include "cl_Cell.hpp"
21#include "cl_Vector.hpp"
22
23namespace belfem
24{
25 namespace mesh
26 {
27 class Node ;
28 class Edge ;
29 class Face ;
30 class Element ;
31
32 class Basis : public graph::Vertex
33 {
34 // for hanging basis
38 uint16_t mNumberOfSources = 0 ;
39 Basis ** mSources = nullptr ;
40 real * mWeights = nullptr ;
41
48 uint8_t mNumberOfDofs = 0 ;
49 graph::Vertex ** mDofs = nullptr ;
50
51//------------------------------------------------------------------------------
52 public:
53//------------------------------------------------------------------------------
54
55 Basis();
56
57 ~Basis() override ;
58
59 // owns mSources, mWeights and mDofs: a shallow copy would free them twice
60 Basis( const Basis & ) = delete ;
61
62 Basis &
63 operator=( const Basis & ) = delete ;
64
65 Basis( Basis && ) = delete ;
66
67 Basis &
68 operator=( Basis && ) = delete ;
69
70//------------------------------------------------------------------------------
71
75 virtual EntityType
76 entity_type() const ;
77
78//------------------------------------------------------------------------------
79
80 virtual uint
81 number_of_nodes() const ;
82
83//------------------------------------------------------------------------------
84
85 virtual uint
86 number_of_edges() const ;
87
88//------------------------------------------------------------------------------
89
90 virtual uint
91 number_of_faces() const ;
92
93//------------------------------------------------------------------------------
94
95 virtual Node *
96 node( const uint aIndex );
97
98//------------------------------------------------------------------------------
99
100 virtual const Node *
101 node( const uint aIndex ) const ;
102
103//------------------------------------------------------------------------------
104
105 virtual Edge *
106 edge( const uint aIndex );
107
108//------------------------------------------------------------------------------
109
110 virtual const Edge *
111 edge( const uint aIndex ) const ;
112
113//------------------------------------------------------------------------------
114
115 virtual Face *
116 face( const uint aIndex=0 );
117
118//------------------------------------------------------------------------------
119
120 virtual const Face *
121 face( const uint aIndex=0 ) const ;
122
123//------------------------------------------------------------------------------
124
125 virtual uint
126 number_of_elements() const ;
127
128//------------------------------------------------------------------------------
129
130 virtual Element *
131 element( const uint aIndex );
132
133//------------------------------------------------------------------------------
134
135 bool
136 is_hanging() const ;
137
138//------------------------------------------------------------------------------
139
140 uint
141 number_of_sources() const ;
142
143//------------------------------------------------------------------------------
144
145 Basis *
146 source( const uint aIndex );
147
148//------------------------------------------------------------------------------
149
150 const Basis *
151 source( const uint aIndex ) const ;
152
153//------------------------------------------------------------------------------
154
155 Node *
156 source_node( const uint aIndex );
157
158//------------------------------------------------------------------------------
159
160 const Node *
161 source_node( const uint aIndex ) const ;
162
163//------------------------------------------------------------------------------
164
165 real
166 weight( const uint aIndex ) const ;
167
168//------------------------------------------------------------------------------
169
170 void
171 set_weight( const uint aIndex, const real aValue );
172
173//------------------------------------------------------------------------------
174
179 void
180 set_sources( Cell< Basis * > & aSources, const Vector< real > & aCoefficients );
181
182//------------------------------------------------------------------------------
183
184 void
185 set_sources( Cell< Basis * > & aSources, const Cell< real > & aCoefficients );
186
187//------------------------------------------------------------------------------
188
189 void
190 set_sources( Cell< Node * > & aSources, const Vector< real > & aCoefficients );
191
192//------------------------------------------------------------------------------
193
194 void
196
197//------------------------------------------------------------------------------
198
202 void
203 allocate_source_container( uint aNumSources );
204
205//------------------------------------------------------------------------------
206
209 void
210 add_source( Basis * aSource, const real aWeight=1.0 );
211
212//------------------------------------------------------------------------------
213
214 void
215 flag_sources();
216
217//------------------------------------------------------------------------------
218
219 void
221
222//------------------------------------------------------------------------------
223
224 void
226
227//------------------------------------------------------------------------------
228
229 void
231
232//------------------------------------------------------------------------------
233
234 void
235 insert_dof( graph::Vertex * aDof );
236
237//------------------------------------------------------------------------------
238
239 uint
240 number_of_dofs() const ;
241
242//------------------------------------------------------------------------------
243
245 dof( const uint aIndex );
246
247//------------------------------------------------------------------------------
248
251 bool
252 holds_dof( const graph::Vertex * aDof ) const ;
253
254//------------------------------------------------------------------------------
255
257 bool
258 has_dof_container() const ;
259
260//------------------------------------------------------------------------------
261 };
262
263//----------------------------------------------------------------------------
264
265 inline bool
267 {
268 return mNumberOfSources > 0 ;
269 }
270
271//----------------------------------------------------------------------------
272
273 inline uint
275 {
276 return mNumberOfSources ;
277 }
278
279
280//------------------------------------------------------------------------------
281
282 inline void
284 {
285 // a wrapped counter would make allocate_dof_container skip its
286 // malloc and insert_dof write through an uninitialized pointer
287 BELFEM_ERROR( mNumberOfDofs < std::numeric_limits< decltype( mNumberOfDofs ) >::max(),
288 "Dof counter of basis %lu is full ( max %lu )",
289 ( long unsigned int ) this->id(),
290 ( long unsigned int ) std::numeric_limits< decltype( mNumberOfDofs ) >::max() );
291
292 ++mNumberOfDofs ;
293 }
294
295//------------------------------------------------------------------------------
296
297 inline void
299 {
300 if( mNumberOfDofs > 0 )
301 {
302 // a second dof manager connecting to the same mesh replaces
303 // the container the first one left; free it, do not leak it
304 free( mDofs );
305 mDofs = ( graph::Vertex ** ) malloc( mNumberOfDofs * sizeof ( graph::Vertex * ) );
306 BELFEM_ERROR( mDofs != nullptr, "Failed to allocate the dof container of basis %lu",
307 ( long unsigned int ) this->id() );
308 std::fill( mDofs, mDofs + mNumberOfDofs, nullptr );
309 mNumberOfDofs = 0 ;
310 }
311 }
312
313//------------------------------------------------------------------------------
314
315 inline void
317 {
318 // keyed on the pointer: a container allocated but not yet filled
319 // has a zero count and must still go
320 free( mDofs );
321 mDofs = nullptr ;
322 mNumberOfDofs = 0 ;
323 }
324
325//------------------------------------------------------------------------------
326
327 inline void
329 {
330 BELFEM_ERROR( mNumberOfDofs < std::numeric_limits< decltype( mNumberOfDofs ) >::max(),
331 "Dof counter of basis %lu is full ( max %lu )",
332 ( long unsigned int ) this->id(),
333 ( long unsigned int ) std::numeric_limits< decltype( mNumberOfDofs ) >::max() );
334
335 mDofs[ mNumberOfDofs++ ] = aDof ;
336 }
337
338//----------------------------------------------------------------------------
339
340 inline uint
342 {
343 return mNumberOfDofs ;
344 }
345
346//----------------------------------------------------------------------------
347
348 inline graph::Vertex *
349 Basis::dof( const uint aIndex )
350 {
351 BELFEM_ASSERT( aIndex < ( uint ) mNumberOfDofs, "Index %u out of bounds for basis %lu (expect < %u).",
352 ( unsigned int ) aIndex,
353 ( long unsigned int ) this->id(),
354 ( unsigned int ) mNumberOfDofs );
355
356 return mDofs[ aIndex ];
357 }
358
359//----------------------------------------------------------------------------
360
361 inline bool
362 Basis::holds_dof( const graph::Vertex * aDof ) const
363 {
364 if ( mDofs != nullptr )
365 {
366 for ( uint k = 0; k < mNumberOfDofs; ++k )
367 {
368 if ( mDofs[ k ] == aDof )
369 {
370 return true ;
371 }
372 }
373 }
374 return false ;
375 }
376
377//----------------------------------------------------------------------------
378
379 inline bool
381 {
382 return mDofs != nullptr ;
383 }
384
385//----------------------------------------------------------------------------
386
387 inline Basis *
388 Basis::source( const uint aIndex )
389 {
390 BELFEM_ASSERT( aIndex < ( uint ) mNumberOfSources, "Index %u out of bounds for basis %lu (must be < %u).",
391 ( unsigned int ) aIndex,
392 ( long unsigned int ) this->id(),
393 ( unsigned int ) mNumberOfSources );
394
395 return mSources[ aIndex ];
396 }
397
398//----------------------------------------------------------------------------
399
400 inline const Basis *
401 Basis::source( const uint aIndex ) const
402 {
403 BELFEM_ASSERT( aIndex < ( uint ) mNumberOfSources, "Index %u out of bounds for basis %lu (must be < %u).",
404 ( unsigned int ) aIndex,
405 ( long unsigned int ) this->id(),
406 ( unsigned int ) mNumberOfSources );
407
408 return mSources[ aIndex ];
409 }
410
411//----------------------------------------------------------------------------
412
413 inline real
414 Basis::weight( const uint aIndex ) const
415 {
416 BELFEM_ASSERT( aIndex < mNumberOfSources, "Index %u out of bounds for basis %lu (must be < %u).",
417 ( unsigned int ) aIndex,
418 ( long unsigned int ) this->id(),
419 ( unsigned int ) mNumberOfSources );
420
421 return mWeights[ aIndex ];
422 }
423
424//----------------------------------------------------------------------------
425
426 inline void
427 Basis::set_weight( const uint aIndex, const real aValue )
428 {
429 BELFEM_ASSERT( aIndex < ( uint ) mNumberOfSources, "Index %u out of bounds for basis %lu (must be < %u).",
430 ( unsigned int ) aIndex,
431 ( long unsigned int ) this->id(),
432 ( unsigned int ) mNumberOfSources );
433
434 mWeights[ aIndex ] = aValue ;
435 }
436//----------------------------------------------------------------------------
437 }
438}
439#endif //BELFEM_CL_MESH_BASIS_HPP
#define BELFEM_ERROR(aCheck,...)
Definition assert.hpp:264
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
A bounds-checked wrapper around std::vector.
Definition cl_Cell.hpp:45
Graph node with an adjacency list; the vertex type the graph algorithms operate on.
Definition cl_Graph_Vertex.hpp:32
Definition cl_Mesh_Basis.hpp:33
Basis & operator=(const Basis &)=delete
virtual Edge * edge(const uint aIndex)
Definition cl_Mesh_Basis.cpp:121
virtual uint number_of_nodes() const
Definition cl_Mesh_Basis.cpp:73
graph::Vertex * dof(const uint aIndex)
Definition cl_Mesh_Basis.hpp:349
void set_weight(const uint aIndex, const real aValue)
Definition cl_Mesh_Basis.hpp:427
bool is_hanging() const
Definition cl_Mesh_Basis.hpp:266
void insert_dof(graph::Vertex *aDof)
Definition cl_Mesh_Basis.hpp:328
void reset_source_container()
Definition cl_Mesh_Basis.cpp:277
void flag_sources()
Definition cl_Mesh_Basis.cpp:380
void add_source(Basis *aSource, const real aWeight=1.0)
Definition cl_Mesh_Basis.cpp:318
bool has_dof_container() const
true while a container is allocated, whatever its count
Definition cl_Mesh_Basis.hpp:380
Basis(const Basis &)=delete
uint number_of_dofs() const
Definition cl_Mesh_Basis.hpp:341
Basis(Basis &&)=delete
uint number_of_sources() const
Definition cl_Mesh_Basis.hpp:274
void set_sources(Cell< Basis * > &aSources, const Vector< real > &aCoefficients)
Stores borrowed pointers to the sources and copies the weights.
Definition cl_Mesh_Basis.cpp:189
virtual Face * face(const uint aIndex=0)
Definition cl_Mesh_Basis.cpp:143
virtual EntityType entity_type() const
returns the type of this vertex
Definition cl_Mesh_Basis.cpp:64
Basis()
Definition cl_Mesh_Basis.cpp:21
void allocate_source_container(uint aNumSources)
Definition cl_Mesh_Basis.cpp:295
virtual Node * node(const uint aIndex)
Definition cl_Mesh_Basis.cpp:100
Basis & operator=(Basis &&)=delete
Node * source_node(const uint aIndex)
Definition cl_Mesh_Basis.cpp:163
virtual uint number_of_elements() const
Definition cl_Mesh_Basis.cpp:46
void reset_dof_container()
Definition cl_Mesh_Basis.hpp:316
virtual uint number_of_edges() const
Definition cl_Mesh_Basis.cpp:82
bool holds_dof(const graph::Vertex *aDof) const
Definition cl_Mesh_Basis.hpp:362
real weight(const uint aIndex) const
Definition cl_Mesh_Basis.hpp:414
virtual uint number_of_faces() const
Definition cl_Mesh_Basis.cpp:91
Basis * source(const uint aIndex)
Definition cl_Mesh_Basis.hpp:388
virtual Element * element(const uint aIndex)
Definition cl_Mesh_Basis.cpp:55
void increment_dof_counter()
Definition cl_Mesh_Basis.hpp:283
void allocate_dof_container()
Definition cl_Mesh_Basis.hpp:298
Special Edge class for NEDELEC-Type elements.
Definition cl_Edge.hpp:30
Lagrange Element baseclass.
Definition cl_Element.hpp:35
Definition cl_Face.hpp:29
Definition cl_Node.hpp:30
Definition cl_EF_EdgeFunction.hpp:24
USER GUIDES:
Definition cl_Capacitor.cpp:16
unsigned int uint
Definition typedefs.hpp:30
T max(const Vector< T > &aVector)
Definition fn_AR_max.hpp:24
EntityType
Definition Mesh_Enums.hpp:116
double real
Definition typedefs.hpp:36