BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
cl_Cell.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_CELL_HPP
13#define BELFEM_CL_CELL_HPP
14
15#include <vector>
16#include <initializer_list>
17#include <algorithm> // for unique and reverse
18#include <iterator> // for std::make_move_iterator
19#include <sstream> // for std::ostringstream (generic print)
20
21#include "typedefs.hpp"
22#include "assert.hpp"
23
24namespace belfem
25{
26 namespace cell
27 {
28 void
29 error_out_of_bounds( const index_t aI, const index_t aN );
30 }
31//------------------------------------------------------------------------------
32
40 template< typename T >
41 class Cell
42 {
43//------------------------------------------------------------------------------
44 private:
45//------------------------------------------------------------------------------
46
47 std::vector< T > mCell;
48
49//------------------------------------------------------------------------------
50 public:
51//------------------------------------------------------------------------------
52
53 Cell() = default ;
54
55//------------------------------------------------------------------------------
56
57 Cell( const std::size_t aReserve )
58 {
59 mCell.reserve( aReserve );
60 }
61
62 Cell( const std::size_t aSize, const T aInitializationValue )
63 {
64 mCell.resize( aSize, aInitializationValue );
65 }
66
67//------------------------------------------------------------------------------
68
69 Cell( const std::initializer_list< T > & aInitList ) :
70 mCell( aInitList )
71 {
72 }
73
74//------------------------------------------------------------------------------
75
76 // Copy constructor - explicit implementation
77 Cell( const Cell< T > & other ) : mCell( other.mCell )
78 {
79 }
80
81//------------------------------------------------------------------------------
82
83 // Move constructor - explicit implementation with noexcept
84 Cell( Cell< T > && other ) noexcept : mCell( std::move( other.mCell ) )
85 {
86 // other.mCell is now in valid but unspecified state (empty for vector)
87 }
88
89//------------------------------------------------------------------------------
90
91 // Copy assignment operator - explicit implementation
92 Cell< T >& operator=( const Cell< T > & other )
93 {
94 if ( this != &other )
95 {
96 mCell = other.mCell;
97 }
98 return *this;
99 }
100
101//------------------------------------------------------------------------------
102
103 // Move assignment operator - explicit implementation with noexcept
104 Cell< T >& operator=( Cell< T > && other ) noexcept
105 {
106 if ( this != &other )
107 {
108 mCell = std::move( other.mCell );
109 // other.mCell is now in valid but unspecified state
110 }
111 return *this;
112 }
113
114//------------------------------------------------------------------------------
115
116 ~Cell() = default;
117
118//------------------------------------------------------------------------------
119
120 T * data()
121 {
122 return mCell.data();
123 }
124
125//------------------------------------------------------------------------------
126
127 const T * data() const
128 {
129 return mCell.data();
130 }
131
132//------------------------------------------------------------------------------
133
134 std::vector< T > &
136 {
137 return mCell;
138 }
139
140//------------------------------------------------------------------------------
141
142 const std::vector< T > &
144 {
145 return mCell;
146 }
147
148//------------------------------------------------------------------------------
149
150 auto
151 operator()( size_t aIndex )
152 -> decltype( mCell[ aIndex ] )
153 {
154 BELFEM_ASSERT( aIndex < mCell.size() ,
155 "Cell index out of bounds: %lu (expect < %lu)",
156 (long unsigned int)aIndex,
157 (long unsigned int)mCell.size() );
158 return mCell[ aIndex ];
159 }
160
161
162//------------------------------------------------------------------------------
163
164 auto
165 operator()( size_t aIndex ) const
166 -> decltype( mCell[ aIndex ] )
167 {
168 BELFEM_ASSERT( aIndex < mCell.size() ,
169 "Cell index out of bounds: %lu (expect < %lu)",
170 (long unsigned int)aIndex,
171 (long unsigned int)mCell.size() );
172 return mCell[ aIndex ];
173 }
174
175//------------------------------------------------------------------------------
176
180 size_t
181 size() const
182 {
183 return mCell.size();
184 }
185
186//------------------------------------------------------------------------------
187
188 void
189 set_size( const size_t aSize )
190 {
191 mCell.resize( aSize );
192 }
193
194//------------------------------------------------------------------------------
195
196 void
197 set_size( const size_t aSize, const T & aValue )
198 {
199 mCell.resize( aSize, aValue );
200 }
201
202//------------------------------------------------------------------------------
203
204 auto
205 begin() -> decltype( mCell.begin() )
206 {
207 return mCell.begin();
208 }
209
210//------------------------------------------------------------------------------
211
212 auto
213 end() -> decltype( mCell.end() )
214 {
215 return mCell.end();
216 }
217
218//------------------------------------------------------------------------------
219
220 auto
221 begin() const -> decltype( mCell.begin() )
222 {
223 return mCell.begin();
224 }
225
226//------------------------------------------------------------------------------
227
228 auto
229 end() const -> decltype( mCell.end() )
230 {
231 return mCell.end();
232 }
233
234//------------------------------------------------------------------------------
235
239 void
241 {
242 mCell.clear();
243 }
244
245//------------------------------------------------------------------------------
246
250 void
251 reserve( const size_t aSize )
252 {
253 mCell.reserve( aSize );
254 }
255
256//------------------------------------------------------------------------------
257
261 void
262 push( const T & aValue )
263 {
264 mCell.push_back( aValue );
265 }
266
267//------------------------------------------------------------------------------
268
272 void
273 push( T && aValue )
274 {
275 mCell.push_back( std::move( aValue ) );
276 }
277
278//------------------------------------------------------------------------------
279
283 template< typename... Args >
284 void
285 emplace( Args&&... args )
286 {
287 mCell.emplace_back( std::forward< Args >( args )... );
288 }
289
290//------------------------------------------------------------------------------
291
295 T
297 {
298 T aPop = std::move( mCell.back() ); // Move instead of copy
299 mCell.pop_back();
300 return aPop;
301 }
302
303
304//------------------------------------------------------------------------------
305
309 void
311 {
312 mCell.shrink_to_fit();
313 }
314
315//------------------------------------------------------------------------------
316
317 T &
319 {
320#if !defined( NDEBUG ) || defined( DEBUG )
321 return mCell.at( 0 );
322#else
323 return mCell[ 0 ];
324#endif
325 }
326
327//------------------------------------------------------------------------------
328
329 const T &
330 first() const
331 {
332#if !defined( NDEBUG ) || defined( DEBUG )
333 return mCell.at( 0 );
334#else
335 return mCell[ 0 ];
336#endif
337 }
338
339//------------------------------------------------------------------------------
340
341 T &
343 {
344#if !defined( NDEBUG ) || defined( DEBUG )
345 return mCell.at( mCell.size()-1 );
346#else
347 return mCell[ mCell.size()-1 ];
348#endif
349 }
350
351//------------------------------------------------------------------------------
352
353 const T &
354 last() const
355 {
356#if !defined( NDEBUG ) || defined( DEBUG )
357 return mCell.at( mCell.size()-1 );
358#else
359 return mCell[ mCell.size()-1 ];
360#endif
361 }
362
363//------------------------------------------------------------------------------
364
368 void
369 swap( Cell< T > & other ) noexcept
370 {
371 mCell.swap( other.mCell );
372 }
373
374//------------------------------------------------------------------------------
375
379 bool
380 empty() const
381 {
382 return mCell.empty();
383 }
384
385//------------------------------------------------------------------------------
386
390 size_t
391 capacity() const
392 {
393 return mCell.capacity();
394 }
395
396//------------------------------------------------------------------------------
397
401 auto
402 insert( typename std::vector< T >::const_iterator pos, const T & value )
403 -> decltype( mCell.insert( pos, value ) )
404 {
405 return mCell.insert( pos, value );
406 }
407
408//------------------------------------------------------------------------------
409
413 auto
414 insert( typename std::vector< T >::const_iterator pos, T && value )
415 -> decltype( mCell.insert( pos, std::move( value ) ) )
416 {
417 return mCell.insert( pos, std::move( value ) );
418 }
419
420//------------------------------------------------------------------------------
421
425 auto
426 erase( typename std::vector< T >::const_iterator pos )
427 -> decltype( mCell.erase( pos ) )
428 {
429 return mCell.erase( pos );
430 }
431
432//------------------------------------------------------------------------------
433
437 auto
438 erase( typename std::vector< T >::const_iterator first,
439 typename std::vector< T >::const_iterator last )
440 -> decltype( mCell.erase( first, last ) )
441 {
442 return mCell.erase( first, last );
443 }
444
445//------------------------------------------------------------------------------
446
447 void
448 print( const std::string aLabel="" ) const ;
449
450//------------------------------------------------------------------------------
451 };
452
453 template< typename T >
454 void
455 sort( Cell< T > & aCell )
456 {
457 // get ref to data
458 std::vector< T > & tVec = aCell.vector_data();
459
460 // sort data
461 std::sort( tVec.begin(), tVec.end() );
462 }
463
464//------------------------------------------------------------------------------
465
466 template< typename T, class C >
467 void
468 sort( Cell< T > & aCell, C & aComp, const size_t aNumberOfItems=0 )
469 {
470 // get ref to data
471 std::vector< T > & tVec = aCell.vector_data();
472
473 // sort data
474 if( aNumberOfItems==0 )
475 {
476 std::sort( tVec.begin(), tVec.end(), aComp );
477 }
478 else
479 {
480 std::sort( tVec.begin(), tVec.begin()+aNumberOfItems, aComp );
481 }
482 }
483
484//------------------------------------------------------------------------------
485
486 template< typename T >
487 void
488 unique( Cell< T > & aCell )
489 {
490 // get ref to data
491 std::vector< T > & tVec = aCell.vector_data();
492
493 // sort data
494 std::sort( tVec.begin(), tVec.end() );
495
496 // trim vector
497 tVec.erase( std::unique( tVec.begin(), tVec.end() ), tVec.end() );
498 }
499
500//------------------------------------------------------------------------------
501
506 template< typename T >
507 index_t
508 find_index_in_unique_cell( const Cell< T > & aCell, const T & aMember )
509 {
510 auto tIterator = std::lower_bound( aCell.vector_data().begin(),
511 aCell.vector_data().end(), aMember );
512
513 BELFEM_ASSERT( tIterator != aCell.vector_data().end()
514 && ! ( aMember < *tIterator ),
515 "member not found in cell (is the cell sorted and unique?)" );
516
517 return tIterator - aCell.vector_data().begin();
518 }
519
520//------------------------------------------------------------------------------
521
522 template< typename T >
523 void
525 {
526 // get ref to data
527 std::vector< T > & tVec = aCell.vector_data();
528
529 // reverse data
530 std::reverse( tVec.begin(), tVec.end() );
531 }
532
533//------------------------------------------------------------------------------
534
535 template< typename T >
536 void
537 append( Cell< T > & aA, const Cell< T > & aB )
538 {
539 // Reserve enough capacity in aA to hold both aA and aB
540 aA.vector_data().reserve(aA.vector_data().size() + aB.vector_data().size());
541
542 // Use std::vector's insert method to append aB's data to aA
543 aA.vector_data().insert(
544 aA.vector_data().end(),
545 aB.vector_data().begin(),
546 aB.vector_data().end()
547 );
548 }
549
550//------------------------------------------------------------------------------
551
552 template< typename T >
553 void
554 append_move( Cell< T > & aTarget, Cell< T > & aSource )
555 {
556 // Reserve enough capacity in aA to hold both aA and aB
557 aTarget.vector_data().reserve(aTarget.vector_data().size() + aSource.vector_data().size());
558
559 // Use std::vector's insert method with move iterators
560 aTarget.vector_data().insert(
561 aTarget.vector_data().end(),
562 std::make_move_iterator(aSource.vector_data().begin()),
563 std::make_move_iterator(aSource.vector_data().end()));
564
565 // Clear aB since its elements have been moved
566 aSource.clear();
567 }
568
569//------------------------------------------------------------------------------
570
574 template< typename T >
575 void
576 swap( Cell< T > & aA, Cell< T > & aB ) noexcept
577 {
578 aA.swap( aB );
579 }
580
581//------------------------------------------------------------------------------
582
583// turn off annoying waning
584#ifdef BELFEM_CLANG
585#pragma clang diagnostic push
586#pragma clang diagnostic ignored "-Wformat-security"
587#elif BELFEM_GCC
588#pragma GCC diagnostic push
589#pragma GCC diagnostic ignored "-Wformat"
590#elif BELFEM_INTEL
591#pragma warning push
592#pragma warning disable 1595
593#endif
594
595 template < typename T > void
596 Cell< T >::print( const std::string aLabel ) const
597 {
598 FILE * tOutFile = stdout;
599
600 fprintf( tOutFile, "\n%s = [ ... \n", aLabel.c_str() );
601
602 const Cell< T > & tThis = *this;
603
604 uint tLength = tThis.size();
605
606 for( uint i=0; i< tLength; ++i )
607 {
608 // use std::ostringstream for generic types (including std::string)
609 std::ostringstream tStream;
610 tStream << tThis( i );
611 fprintf( tOutFile, "%s; ", tStream.str().c_str() );
612
613 if( i < tLength-1 )
614 {
615 fprintf( tOutFile, "...\n" );
616 }
617 else
618 {
619 fprintf( tOutFile, "];\n" );
620 }
621 }
622 }
623
624// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
625
626 template <>
627 inline void
628 Cell< real >::print( const std::string aLabel ) const
629 {
630 FILE * tOutFile = stdout;
631
632 fprintf( tOutFile, "%s = [ ... \n", aLabel.c_str() );
633
634 const Cell< real > & tThis = *this;
635
636 uint tLength = tThis.size();
637
638 for( uint i=0; i< tLength; ++i )
639 {
640
641 fprintf( tOutFile, "%+.15e; ", ( double ) tThis( i ) );
642
643
644 if( i < tLength-1 )
645 {
646 fprintf( tOutFile, "...\n" );
647 }
648 else
649 {
650 fprintf( tOutFile, "];\n" );
651 }
652 }
653 }
654
655#ifdef BELFEM_CLANG
656#pragma clang diagnostic pop
657#elif BELFEM_GCC
658#pragma GCC diagnostic pop
659#elif BELFEM_INTEL
660#pragma warning pop
661#endif
662
663
664//------------------------------------------------------------------------------
665} /* namespace belfem */
666
667#endif //BELFEM_CL_CELL_HPP
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
Cell is a wrapper around the standard vector.
Definition cl_Cell.hpp:42
T pop()
pop an entry from the Cell
Definition cl_Cell.hpp:296
Cell(const Cell< T > &other)
Definition cl_Cell.hpp:77
auto begin() const -> decltype(mCell.begin())
Definition cl_Cell.hpp:221
void print(const std::string aLabel="") const
Definition cl_Cell.hpp:596
bool empty() const
Check if Cell is empty.
Definition cl_Cell.hpp:380
void set_size(const size_t aSize)
Definition cl_Cell.hpp:189
Cell(const std::initializer_list< T > &aInitList)
Definition cl_Cell.hpp:69
T & first()
Definition cl_Cell.hpp:318
size_t size() const
return the size of the Cell
Definition cl_Cell.hpp:181
auto erase(typename std::vector< T >::const_iterator pos) -> decltype(mCell.erase(pos))
Erase element at position.
Definition cl_Cell.hpp:426
void swap(Cell< T > &other) noexcept
Swap contents with another Cell.
Definition cl_Cell.hpp:369
void emplace(Args &&... args)
emplace an entry at the end (construct in-place)
Definition cl_Cell.hpp:285
const T & last() const
Definition cl_Cell.hpp:354
size_t capacity() const
Get capacity.
Definition cl_Cell.hpp:391
void clear()
clear the memory
Definition cl_Cell.hpp:240
auto begin() -> decltype(mCell.begin())
Definition cl_Cell.hpp:205
void set_size(const size_t aSize, const T &aValue)
Definition cl_Cell.hpp:197
Cell(Cell< T > &&other) noexcept
Definition cl_Cell.hpp:84
Cell< T > & operator=(const Cell< T > &other)
Definition cl_Cell.hpp:92
T & last()
Definition cl_Cell.hpp:342
const T * data() const
Definition cl_Cell.hpp:127
auto end() -> decltype(mCell.end())
Definition cl_Cell.hpp:213
std::vector< T > & vector_data()
Definition cl_Cell.hpp:135
auto insert(typename std::vector< T >::const_iterator pos, T &&value) -> decltype(mCell.insert(pos, std::move(value)))
Insert element at position (move version).
Definition cl_Cell.hpp:414
Cell()=default
auto insert(typename std::vector< T >::const_iterator pos, const T &value) -> decltype(mCell.insert(pos, value))
Insert element at position (copy version).
Definition cl_Cell.hpp:402
Cell< T > & operator=(Cell< T > &&other) noexcept
Definition cl_Cell.hpp:104
Cell(const std::size_t aReserve)
Definition cl_Cell.hpp:57
void push(const T &aValue)
push an entry to the end of the cell (copy version)
Definition cl_Cell.hpp:262
auto end() const -> decltype(mCell.end())
Definition cl_Cell.hpp:229
void reserve(const size_t aSize)
reserve memory
Definition cl_Cell.hpp:251
void shrink_to_fit()
free unused memory
Definition cl_Cell.hpp:310
~Cell()=default
const T & first() const
Definition cl_Cell.hpp:330
const std::vector< T > & vector_data() const
Definition cl_Cell.hpp:143
T * data()
Definition cl_Cell.hpp:120
auto operator()(size_t aIndex) -> decltype(mCell[aIndex])
Definition cl_Cell.hpp:151
Cell(const std::size_t aSize, const T aInitializationValue)
Definition cl_Cell.hpp:62
void push(T &&aValue)
push an entry to the end of the cell (move version)
Definition cl_Cell.hpp:273
auto erase(typename std::vector< T >::const_iterator first, typename std::vector< T >::const_iterator last) -> decltype(mCell.erase(first, last))
Erase range of elements.
Definition cl_Cell.hpp:438
auto operator()(size_t aIndex) const -> decltype(mCell[aIndex])
Definition cl_Cell.hpp:165
Definition cl_Cell.cpp:19
void error_out_of_bounds(const index_t aI, const index_t aN)
Definition cl_Cell.cpp:21
USER GUIDES:
Definition cl_Capacitor.cpp:16
void reverse(Cell< T > &aCell)
Definition cl_Cell.hpp:524
void append(Cell< T > &aA, const Cell< T > &aB)
Definition cl_Cell.hpp:537
std::pair< real, unit > value
Definition typedefs.hpp:74
void swap(Cell< T > &aA, Cell< T > &aB) noexcept
Swap specialization for Cell.
Definition cl_Cell.hpp:576
unsigned int uint
Definition typedefs.hpp:30
void unique(Cell< T > &aCell)
Definition cl_Cell.hpp:488
index_t find_index_in_unique_cell(const Cell< T > &aCell, const T &aMember)
returns the position of a member inside a cell.
Definition cl_Cell.hpp:508
void sort(Cell< T > &aCell)
Definition cl_Cell.hpp:455
uint32_t index_t
Definition typedefs.hpp:52
void append_move(Cell< T > &aTarget, Cell< T > &aSource)
Definition cl_Cell.hpp:554