DUNE-FEM (unstable)

dynamicarray.hh
1#ifndef DUNE_FEM_DYNAMICARRAY_HH
2#define DUNE_FEM_DYNAMICARRAY_HH
3
4#include <algorithm>
5#include <cassert>
6#include <cmath>
7#include <cstdlib>
8#include <cstring>
9#include <iostream>
10#include <memory>
11#include <type_traits>
12
15#include <dune/fem/common/utility.hh>
16
17namespace Dune
18{
19
20 namespace Fem
21 {
22 // forward declaration
23 template< class K > class StaticArray;
24
26 template <typename T>
28 : public std::allocator< T >
29 {
30 typedef std::allocator< T > BaseType;
31 public:
32#if __cplusplus <= 201703L
33 typedef typename BaseType :: pointer pointer ;
34#else
35 typedef T* pointer;
36#endif
37 typedef typename BaseType :: size_type size_type;
38
39 pointer allocate( size_type n )
40 {
41 return new T[ n ];
42 }
43
44 void deallocate( pointer p, size_type n )
45 {
46 delete [] p;
47 }
48
49 pointer reallocate ( pointer oldMem, size_type oldSize, size_type n )
50 {
51 assert(oldMem);
52 pointer p = allocate( n );
53 const size_type copySize = std::min( oldSize, n );
54 std::copy( oldMem, oldMem+copySize, p );
55 deallocate( oldMem, oldSize );
56 return p;
57 }
58 };
59
62 template <typename T>
63 class PODArrayAllocator : public std::allocator< T >
64 {
65 static_assert( Std::is_pod< T > :: value, "T is not POD" );
66 typedef std::allocator< T > BaseType;
67 public:
68 PODArrayAllocator() = default;
69
70#if __cplusplus <= 201703L
71 typedef typename BaseType :: pointer pointer ;
72#else
73 typedef T* pointer;
74#endif
75 typedef typename BaseType :: size_type size_type;
76 typedef typename BaseType :: value_type value_type;
77
79 pointer allocate( size_type n )
80 {
81 pointer p = static_cast< pointer > (std::malloc(n * sizeof(value_type)));
82 assert(p);
83 return p;
84 }
85
87 void deallocate( pointer p, size_type n )
88 {
89 assert(p);
90 std::free(p);
91 }
92
94 pointer reallocate (pointer oldMem, size_type oldSize , size_type n)
95 {
96 assert(oldMem);
97 pointer p = static_cast< pointer > (std::realloc(oldMem , n*sizeof(value_type)));
98 assert(p);
99 return p;
100 }
101 };
102
103 template <class T, class AllocatorType = typename std::conditional< Std::is_pod< T > :: value,
104 PODArrayAllocator< T >,
105 StandardArrayAllocator< T > > :: type >
106 class DynamicArray;
107
108 } // end namespace Fem
109
110 // specialization of DenseMatVecTraits for StaticArray
111 template< class K >
112 struct DenseMatVecTraits< Fem::StaticArray< K > >
113 {
114 typedef Fem::StaticArray< K > derived_type;
115 typedef K* container_type;
116 typedef K value_type;
117 typedef std::size_t size_type;
118 };
119
120 template< class K >
121 struct FieldTraits< Fem::StaticArray< K > >
122 {
123 typedef typename FieldTraits< K >::field_type field_type;
124 typedef typename FieldTraits< K >::real_type real_type;
125 };
126
127 // specialization of DenseMatVecTraits for DynamicArray
128 template< class K >
129 struct DenseMatVecTraits< Fem::DynamicArray< K > > : public DenseMatVecTraits< Fem::StaticArray< K > >
130 {
131 };
132
133 template< class K >
134 struct FieldTraits< Fem::DynamicArray< K > > : public FieldTraits< Fem::StaticArray< K > >
135 {
136 };
137
138 namespace Fem
139 {
140
141
146 template <class T>
147 class StaticArray : public DenseVector< StaticArray< T > >
148 {
151
152 public:
153 typedef typename BaseType::size_type size_type;
154
155 typedef typename BaseType::value_type value_type;
156 typedef value_type FieldType;
157
158 typedef typename DenseMatVecTraits< ThisType >::container_type DofStorageType;
159
160 StaticArray(const ThisType&) = delete;
161
163 explicit StaticArray(size_type size, const value_type* vec)
164 : vec_( const_cast< DofStorageType > (vec) )
165 , size_(size)
166 {
167 }
168
170 size_type size () const
171 {
172 return size_;
173 }
174
176 value_type& operator [] ( size_type i )
177 {
178 assert( i < size_ );
179 return vec_[i];
180 }
181
183 const value_type& operator [] ( size_type i ) const
184 {
185 assert( i < size_ );
186 return vec_[i];
187 }
188
191 {
192 assert(org.size_ >= size() );
193 assert( ( size_ > 0 ) ? vec_ != nullptr : true );
194 std::copy(org.vec_, org.vec_ + size_, vec_ );
195 return *this;
196 }
197
199 void clear ()
200 {
201 std::fill( vec_, vec_+size_, value_type(0) );
202 }
203
205 void memmove(size_type length, size_type oldStartIdx, size_type newStartIdx)
206 {
207 void * dest = ((void *) (&vec_[newStartIdx]));
208 const void * src = ((const void *) (&vec_[oldStartIdx]));
209 std::memmove(dest, src, length * sizeof(value_type));
210 }
211
214 bool operator==(const ThisType& other) const
215 {
216 return vec_ == other.vec_;
217 }
218
220 value_type* data()
221 {
222 return vec_;
223 }
224
226 const value_type* data() const
227 {
228 return vec_;
229 }
230
231 protected:
232 DofStorageType vec_;
233 size_type size_;
234 };
235
236
242 template <class T, class Allocator>
243 class DynamicArray : public StaticArray<T>
244 {
245 public:
246 typedef Allocator AllocatorType;
247 protected:
249 typedef StaticArray<T> BaseType;
250
251 using BaseType :: size_ ;
252 using BaseType :: vec_ ;
253
254 public:
255 using BaseType :: size ;
256
257 typedef typename BaseType::size_type size_type;
258 typedef typename BaseType::value_type value_type;
259
261 DynamicArray(const ThisType& other)
262 : BaseType(0, nullptr)
263 , memoryFactor_(1.0)
264 , memSize_(0)
265 , allocator_( other.allocator_ )
266 {
267 assign( other );
268 }
269
271 explicit DynamicArray(size_type size,
272 const value_type& value,
273 AllocatorType allocator = AllocatorType() )
274 : BaseType(size, (size == 0) ? nullptr : allocator.allocate(size) )
275 , memoryFactor_(1.0)
276 , memSize_(size)
277 , allocator_( allocator )
278 {
279 if( size_ > 0 )
280 {
281 std::fill( vec_, vec_+size_, value );
282 }
283 }
284
286 explicit DynamicArray(size_type size = 0,
287 AllocatorType allocator = AllocatorType() )
288 : BaseType(size, (size == 0) ? nullptr : allocator.allocate(size) )
289 , memoryFactor_(1.0)
290 , memSize_(size)
291 , allocator_( allocator )
292 {
293 }
294
296 void setMemoryFactor(double memFactor)
297 {
298 memoryFactor_ = memFactor;
299 assert( memoryFactor_ >= 1.0 );
300 }
301
304 {
305 freeMemory();
306 }
307
309 size_type capacity () const
310 {
311 return memSize_;
312 }
313
315 void assign (const ThisType & org)
316 {
317 memoryFactor_ = org.memoryFactor_;
318 assert( memoryFactor_ >= 1.0 );
319
320 resize( org.size_ );
321 assert( ( size_ > 0 ) ? vec_ != nullptr : true );
322 std::copy(org.vec_, org.vec_ + size_, vec_ );
323 }
324
327 {
328 assign( org );
329 return *this;
330 }
331
334 void resize ( size_type nsize )
335 {
336 // only initialize value if we are not using a POD type
337 doResize( nsize, ! Std::is_pod< value_type >::value );
338 }
339
342 void resize ( size_type nsize, const value_type& value )
343 {
344 doResize( nsize, true, value );
345 }
346
347 void doResize( size_type nsize, bool initializeNewValues, const value_type& value = value_type() )
348 {
349 // just set size if nsize is smaller than memSize but larger the half of memSize
350 if( (nsize <= memSize_) && (nsize >= (memSize_/2)) )
351 {
352 size_ = nsize;
353 return ;
354 }
355
356 // if nsize == 0 freeMemory
357 if( nsize == 0 )
358 {
359 freeMemory();
360 return ;
361 }
362
363 // reserve or shrink to memory + overestimate
364 adjustMemory( nsize, initializeNewValues, value );
365 // set new size
366 size_ = nsize;
367 }
368
371 void reserve ( size_type mSize )
372 {
373 // check whether we already have the mem size and if just do nothing
374 if( mSize <= memSize_ )
375 {
376 return ;
377 }
378
379 // adjust memory accordingly
380 adjustMemory( mSize, false );
381 }
382
384 size_type usedMemorySize() const
385 {
386 return memSize_ * sizeof(value_type) + sizeof(ThisType);
387 }
388
389 protected:
391 void adjustMemory( size_type mSize, bool initializeNewValues, const value_type& value = value_type() )
392 {
393 assert( memoryFactor_ >= 1.0 );
394 const double overEstimate = memoryFactor_ * mSize;
395 const size_type nMemSize = (size_type) std::ceil( overEstimate );
396 assert( nMemSize >= mSize );
397
398 if( vec_ == nullptr )
399 {
400 // allocate new memory
401 vec_ = allocator_.allocate( nMemSize );
402 if( initializeNewValues )
403 {
404 std::fill( vec_, vec_+nMemSize, value );
405 }
406 }
407 else
408 {
409 assert( nMemSize > 0 );
410 assert( vec_ );
411
412 // reallocate memory
413 vec_ = allocator_.reallocate (vec_, memSize_, nMemSize);
414 if( nMemSize > memSize_ && initializeNewValues )
415 {
416 std::fill( vec_+memSize_, vec_+nMemSize, value );
417 }
418 }
419
420 // set new mem size
421 memSize_ = nMemSize;
422 }
423
424 // free memory and reset sizes
425 void freeMemory()
426 {
427 if( vec_ != nullptr )
428 {
429 allocator_.deallocate( vec_, memSize_ );
430 vec_ = nullptr;
431 }
432 size_ = 0;
433 memSize_ = 0;
434 }
435
436 double memoryFactor_;
437 size_type memSize_;
438 AllocatorType allocator_;
439 };
440
441 } // namespace Fem
442
443} // namespace Dune
444#endif // #ifndef DUNE_FEM_DYNAMICARRAY_HH
Interface for a class of dense vectors over a given field.
Definition: densevector.hh:229
Traits::value_type value_type
export the type representing the field
Definition: densevector.hh:250
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densevector.hh:259
An implementation of DenseVector which uses a C-array of dynamic size as storage.
Definition: dynamicarray.hh:244
ThisType & operator=(const ThisType &org)
assign arrays
Definition: dynamicarray.hh:326
void setMemoryFactor(double memFactor)
set memory factor
Definition: dynamicarray.hh:296
void adjustMemory(size_type mSize, bool initializeNewValues, const value_type &value=value_type())
adjust the memory
Definition: dynamicarray.hh:391
void assign(const ThisType &org)
assign arrays
Definition: dynamicarray.hh:315
void reserve(size_type mSize)
Definition: dynamicarray.hh:371
size_type capacity() const
return number of total enties of array
Definition: dynamicarray.hh:309
void resize(size_type nsize)
Definition: dynamicarray.hh:334
void resize(size_type nsize, const value_type &value)
Definition: dynamicarray.hh:342
DynamicArray(const ThisType &other)
copy constructor
Definition: dynamicarray.hh:261
DynamicArray(size_type size=0, AllocatorType allocator=AllocatorType())
create array of length size without initializing the values
Definition: dynamicarray.hh:286
~DynamicArray()
destructor
Definition: dynamicarray.hh:303
size_type usedMemorySize() const
return size of vector in bytes
Definition: dynamicarray.hh:384
DynamicArray(size_type size, const value_type &value, AllocatorType allocator=AllocatorType())
create array of length size with initialized values
Definition: dynamicarray.hh:271
Definition: dynamicarray.hh:64
void deallocate(pointer p, size_type n)
release memory previously allocated with malloc member
Definition: dynamicarray.hh:87
pointer reallocate(pointer oldMem, size_type oldSize, size_type n)
allocate array of nmemb objects of type T
Definition: dynamicarray.hh:94
pointer allocate(size_type n)
allocate array of nmemb objects of type T
Definition: dynamicarray.hh:79
oriented to the STL Allocator funtionality
Definition: dynamicarray.hh:29
An implementation of DenseVector which uses a C-array of fixed size as storage.
Definition: dynamicarray.hh:148
value_type & operator[](size_type i)
random access operator
Definition: dynamicarray.hh:176
size_type size() const
return size of array
Definition: dynamicarray.hh:170
ThisType & operator=(const ThisType &org)
copy assignament
Definition: dynamicarray.hh:190
bool operator==(const ThisType &other) const
Definition: dynamicarray.hh:214
value_type * data()
return pointer to data
Definition: dynamicarray.hh:220
void clear()
set all entries to 0
Definition: dynamicarray.hh:199
StaticArray(size_type size, const value_type *vec)
create array of length size and store vec as pointer to memory
Definition: dynamicarray.hh:163
void memmove(size_type length, size_type oldStartIdx, size_type newStartIdx)
move memory from old to new destination
Definition: dynamicarray.hh:205
const value_type * data() const
return pointer to data
Definition: dynamicarray.hh:226
Implements the dense vector interface, with an exchangeable storage class.
Type traits to determine the type of reals (when working with complex numbers)
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)