dune-fem  2.4.1-rc
arrays.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_ARRAYS_HH
2 #define DUNE_FEM_ARRAYS_HH
3 
4 //- System includes
5 #include <cassert>
6 #include <cmath>
7 #include <cstring>
8 #include <cstdlib>
9 #include <iostream>
10 
11 #include <string>
12 
13 //- Dune includes
14 #include <dune/common/genericiterator.hh>
15 #include <dune/common/exceptions.hh>
16 #include <dune/common/version.hh>
17 
18 #if HAVE_BLAS
19 // include BLAS for daxpy operation
20 #include <dune/fem/solver/oemsolver/cblas.h>
21 #endif
22 
24 
25 namespace Dune
26 {
27 
28  namespace Fem
29  {
30 
31  // forward declarations
32  template <class T>
34 
35  template <class T, class AllocatorType = DefaultDofAllocator<T> >
36  class MutableArray;
37 
38  template<class ArrayType>
40 
41 
43  template <class T>
44  class DefaultDofAllocator {
45  public:
47  static T* malloc (size_t nmemb)
48  {
49  assert(nmemb > 0);
50  T* p = new T [ nmemb ] ;
51  assert( p );
52  return p;
53  }
54 
56  static void free (T* p)
57  {
58  delete [] p;
59  }
60 
62  static T* realloc (T* oldMem, size_t oldSize , size_t nmemb)
63  {
64  assert(oldMem);
65  assert(nmemb > 0);
66  T* p = malloc(nmemb);
67  const size_t copySize = std::min( oldSize, nmemb );
68  std::copy( oldMem, oldMem+copySize, p );
69  free (oldMem);
70  return p;
71  }
72  };
73 
76  template <typename T>
78  {
80  static T* malloc (size_t nmemb)
81  {
82  assert(nmemb > 0);
83  T* p = (T *) std::malloc(nmemb * sizeof(T));
84  assert(p);
85  return p;
86  }
87 
89  static void free (T* p)
90  {
91  assert(p);
92  std::free(p);
93  }
94 
96  static T* realloc (T* oldMem, size_t oldSize , size_t nmemb)
97  {
98  assert(nmemb > 0);
99  assert(oldMem);
100  T * p = (T *) std::realloc(oldMem , nmemb*sizeof(T));
101  assert(p);
102  return p;
103  }
104  };
105 
106  template <>
107  struct DefaultDofAllocator<double> : public SimpleDofAllocator< double >
108  {
109  };
110 
111  template <>
112  struct DefaultDofAllocator< float > : public SimpleDofAllocator< float >
113  {
114  };
115 
116  template <>
117  struct DefaultDofAllocator< int > : public SimpleDofAllocator< int >
118  {
119  };
120 
121  template <>
122  struct DefaultDofAllocator< size_t > : public SimpleDofAllocator< size_t >
123  {
124  };
125 
126  template <>
127  struct DefaultDofAllocator< char > : public SimpleDofAllocator< char >
128  {
129  };
130 
131  template <>
132  struct DefaultDofAllocator< bool > : public SimpleDofAllocator< bool >
133  {
134  };
135 
140  template <class T>
142  {
143  protected:
145 
146  // pointer to mem
147  T * vec_;
148 
149  // size of array
150  size_t size_;
151 
152  StaticArray(const StaticArray&);
153  public:
154  typedef T FieldType;
156  typedef T value_type;
157 
159  typedef T block_type;
160 
162  typedef GenericIterator<ThisType, T> DofIteratorType;
163 
165  typedef DofIteratorType iterator ;
166 
168  typedef GenericIterator<const ThisType, const T> ConstDofIteratorType;
169 
171  typedef ConstDofIteratorType const_iterator ;
172 
174  typedef size_t size_type;
175 
177  explicit StaticArray(const size_t size, T* vec)
178  : vec_(vec)
179  , size_(size)
180  {
181  //assert( size_ >= 0 );
182  }
183 
185  explicit StaticArray(const size_t size, const T* vec)
186  : vec_( const_cast< T * > (vec) )
187  , size_(size)
188  {
189  //assert( size_ >= 0 );
190  }
191 
193  DofIteratorType begin() {
194  return DofIteratorType(*this, 0);
195  }
196 
198  ConstDofIteratorType begin() const {
199  return ConstDofIteratorType(*this, 0);
200  }
201 
203  DofIteratorType end() {
204  return DofIteratorType(*this, size_);
205  }
206 
208  ConstDofIteratorType end() const {
209  return ConstDofIteratorType(*this, size_);
210  }
211 
213  size_t size () const { return size_; }
214 
215  private:
216  void assertIndex ( const size_t i ) const
217  {
218 #ifndef NDEBUG
219  if( i >= size() )
220  {
221  std::cerr << std::endl;
222  std::cerr << "Error in StaticArray: Index out of Range: " << i << std::endl;
223  std::cerr << " Size of array: " << size() << std::endl;
224  abort();
225  }
226 #endif
227  }
228 
229  public:
231  T& operator [] ( const size_t i )
232  {
233  assertIndex( i );
234  return vec_[i];
235  }
236 
238  const T& operator [] ( const size_t i ) const
239  {
240  assertIndex( i );
241  return vec_[i];
242  }
243 
245  ThisType& operator= (const ThisType & org)
246  {
247  assert(org.size_ >= size() );
248  assert( ( size_ > 0 ) ? vec_ != 0 : true );
249  // copy the entries
250  std::copy(org.vec_, org.vec_ + size_, vec_ );
251  return *this;
252  }
253 
255  ThisType& operator += (const ThisType & org)
256  {
257  assert(org.size_ >= size() );
258  const size_t s = size();
259  const T * ov = org.vec_;
260  for(size_t i=0; i<s; ++i) vec_[i] += ov[i];
261  return *this;
262  }
263 
265  ThisType& operator -= (const ThisType& org)
266  {
267  assert(org.size() >= size() );
268  const size_t s = size();
269  const T * ov = org.vec_;
270  for(size_t i=0; i<s; ++i) vec_[i] -= ov[i];
271  return *this;
272  }
273 
275  ThisType& operator *= (const T scalar)
276  {
277  const size_t s = size();
278  for(size_t i=0; i<s; ++i) vec_[i] *= scalar;
279  return *this;
280  }
281 
283  ThisType& operator /= (const T scalar)
284  {
285  const T scalar_1 = (((T) 1)/scalar);
286  const size_t s = size();
287  for(size_t i=0; i<s; ++i) vec_[i] *= scalar_1;
288  return *this;
289  }
290 
292  ThisType& operator= (const T scalar)
293  {
294  const size_t s = size();
295  for(size_t i=0; i<s; ++i) vec_[i] = scalar;
296  return *this;
297  }
298 
300  void axpy (const ThisType& org, const T scalar)
301  {
302  const size_t s = size();
303  const T * ov = org.vec_;
304  for(size_t i=0; i<s; ++i) vec_[i] += scalar*ov[i];
305  }
306 
308  void clear ()
309  {
310  const size_t s = size();
311  for(size_t i=0; i<s; ++i) vec_[i] = 0;
312  }
313 
315  void memmove(const int length, const int oldStartIdx, const int newStartIdx)
316  {
317  void * dest = ((void *) (&vec_[newStartIdx]));
318  const void * src = ((const void *) (&vec_[oldStartIdx]));
319  std::memmove(dest, src, length * sizeof(T));
320  }
321 
325  bool operator==(const ThisType& other) const
326  {
327  return vec_ == other.vec_;
328  }
329 
331  T* leakPointer() { return vec_; }
333  const T* leakPointer() const { return vec_; }
334 
336  T* data() { return vec_; }
338  const T* data() const { return vec_; }
339 
341  template <class StreamTraits>
343  {
344  const uint64_t len = size_;
345  out << len;
346  for(size_t i=0; i<size_; ++i)
347  {
348  out << vec_[i];
349  }
350  return true;
351  }
352 
354  template <class StreamTraits>
356  {
357  uint64_t len;
358  in >> len;
359  // when read check size
360  if( size_ != len )
361  {
362  DUNE_THROW(InvalidStateException,"StaticArray::read: internal size " << size_ << " and size to read " << len << " not equal!");
363  }
364 
365  for(size_t i=0; i<size_; ++i)
366  {
367  in >> vec_[i];
368  }
369  return true;
370  }
371 
373  void print(std::ostream& s) const
374  {
375  s << "Print StaticArray(addr = "<< this << ") (size = " << size_ << ")\n";
376  for(size_t i=0; i<size(); ++i)
377  {
378  s << vec_[i] << "\n";
379  }
380  }
381  };
382 
383  // specialisations of axpy
384  template <>
385  inline void StaticArray<double>::axpy(const ThisType& org, const double scalar)
386  {
387 #if HAVE_BLAS
388  DuneCBlas :: daxpy( size() , scalar, org.vec_, 1 , vec_, 1);
389 #else
390  const size_t s = size();
391  const double* ov = org.vec_;
392  for(size_t i=0; i<s; ++i) vec_[i] += scalar * ov[i];
393 #endif
394  }
395 
396  // specialisations of clear
397  template <>
399  {
400  std::memset(vec_, 0 , size() * sizeof(int));
401  }
402  template <>
404  {
405  std::memset(vec_, 0 , size() * sizeof(double));
406  }
407 
417  template <class T, class AllocatorType>
418  class MutableArray : public StaticArray<T>
419  {
420  protected:
423 
424  using BaseType :: size_ ;
425  using BaseType :: vec_ ;
426 
427  // make new memory memFactor larger
429 
430  // actual capacity of array
431  size_t memSize_;
432 
433  public:
434  using BaseType :: size ;
435 
438  : BaseType(0, (T *) 0)
439  , memoryFactor_(1.0)
440  , memSize_(0)
441  {
442  }
443 
446  : BaseType(0, (T *) 0),
447  memoryFactor_(1.0),
448  memSize_(0)
449  {
450  // assign vector
451  *this = other;
452  }
453 
455  MutableArray(const size_t size)
456  : BaseType(size,
457  // only alloc memory if size > 0
458  ((T *) (size == 0) ? 0 : AllocatorType :: malloc (size)))
459  , memoryFactor_(1.0)
460  , memSize_(size)
461  {
462  }
463 
465  void setMemoryFactor(const double memFactor)
466  {
467  memoryFactor_ = memFactor;
468  }
469 
472  {
473  freeMemory();
474  }
475 
477  size_t capacity () const { return memSize_; }
478 
480  ThisType& operator= (const ThisType & org)
481  {
482  resize( org.size_ );
483  memoryFactor_ = org.memoryFactor_;
484  assert( ( size_ > 0 ) ? vec_ != 0 : true );
485  std::copy(org.vec_, org.vec_ + size_, vec_ );
486  return *this;
487  }
488 
491  void resize ( size_t nsize )
492  {
493  // just set size if nsize is smaller than memSize but larger the
494  // half of memSize
495  if( (nsize <= memSize_) && (nsize >= (memSize_/2)) )
496  {
497  size_ = nsize;
498  return ;
499  }
500 
501  // if nsize == 0 freeMemory
502  if( nsize == 0 )
503  {
504  freeMemory();
505  return ;
506  }
507 
508  // reserve or shrink to memory + overestimate
509  adjustMemory( nsize );
510  // set new size
511  size_ = nsize;
512  }
513 
517  void reserve ( size_t mSize )
518  {
519  // check whether we already have the mem size
520  // and if just do nothing
521  if( mSize <= memSize_ )
522  {
523  return ;
524  }
525 
526  // adjust memory accordingly
527  adjustMemory( mSize );
528  }
529 
531  size_t usedMemorySize() const
532  {
533  return memSize_ * sizeof(T) + sizeof(ThisType);
534  }
535 
536  protected:
538  void adjustMemory( size_t mSize )
539  {
540  assert( memoryFactor_ >= 1.0 );
541  const double overEstimate = memoryFactor_ * mSize;
542  const size_t nMemSize = (size_t) std::ceil( overEstimate );
543  assert( nMemSize >= mSize );
544 
545  if( !vec_ )
546  {
547  // allocate new memory
548  vec_ = AllocatorType :: malloc(nMemSize);
549  }
550  else
551  {
552  assert( nMemSize > 0 );
553  // nsize is the minimum needed size of the vector
554  // we double this size to reserve some memory and minimize
555  // reallocations
556  assert( vec_ );
557 
558  // reallocate memory
559  vec_ = AllocatorType :: realloc (vec_,memSize_,nMemSize);
560  }
561 
562  // set new mem size
563  memSize_ = nMemSize;
564  }
565 
566  // free memory and reset sizes
567  void freeMemory()
568  {
569  if( vec_ )
570  {
571  AllocatorType :: free ( vec_ );
572  vec_ = 0;
573  }
574  size_ = 0;
575  memSize_ = 0;
576  }
577  };
578 
580  template<class ValueType>
581  struct SpecialArrayFeatures<MutableArray<ValueType> >
582  {
584  static size_t used(const ArrayType & array)
585  {
586  return array.usedMemorySize();
587  }
588  static inline void setMemoryFactor(ArrayType & array, const double memFactor)
589  {
590  array.setMemoryFactor(memFactor);
591  }
592 
593  static inline void memMoveBackward(ArrayType& array,
594  const size_t length,
595  const size_t oldStartIdx,
596  const size_t newStartIdx)
597  {
598  assert( newStartIdx >= oldStartIdx );
599  //array.memmove(length,oldStartIdx,newStartIdx);
600  // get new end of block which is offSet + (length of block - 1)
601  size_t newIdx = newStartIdx + length - 1;
602  assert( newIdx < array.size() );
603  // copy all entries backwards
604  for(size_t oldIdx = oldStartIdx + length-1; oldIdx >= oldStartIdx; --oldIdx, --newIdx )
605  {
606  assert( oldIdx < array.size() );
607  // move value to new location
608  array[newIdx] = array[oldIdx];
609 #ifndef NDEBUG
610  // for debugging purpose
611  array[oldIdx ] = 0.0;
612 #endif
613  }
614  }
615  static inline void memMoveForward(ArrayType& array,
616  const size_t length,
617  const size_t oldStartIdx,
618  const size_t newStartIdx)
619  {
620  assert( newStartIdx <= oldStartIdx );
621  //array.memmove(length,oldStartIdx,newStartIdx);
622  const size_t upperBound = oldStartIdx + length;
623  // get new off set that should be smaller then old one
624  size_t newIdx = newStartIdx;
625  for(size_t oldIdx = oldStartIdx; oldIdx<upperBound; ++oldIdx, ++newIdx )
626  {
627  // copy to new location
628  array[newIdx] = array[oldIdx];
629 #ifndef NDEBUG
630  // for debugging issues only
631  array[oldIdx] = 0.0;
632 #endif
633  }
634  }
635 
636  static inline
637  void assign( ArrayType& array, const int newIndex, const int oldIndex )
638  {
639  array[ newIndex ] = array[ oldIndex ];
640  }
641  };
642 
643  } // namespace Fem
644 
645 } // namespace Dune
646 #endif // #ifndef DUNE_FEM_ARRAYS_HH
static T * realloc(T *oldMem, size_t oldSize, size_t nmemb)
allocate array of nmemb objects of type T
Definition: arrays.hh:96
size_t capacity() const
return number of total enties of array
Definition: arrays.hh:477
void print(std::ostream &s) const
print array
Definition: arrays.hh:373
void clear()
set all entries to zero
Definition: arrays.hh:308
bool read(InStreamInterface< StreamTraits > &in)
write to stream
Definition: arrays.hh:355
static void setMemoryFactor(ArrayType &array, const double memFactor)
Definition: arrays.hh:588
size_t size() const
return number of enties of array
Definition: arrays.hh:213
MutableArray< ValueType > ArrayType
Definition: arrays.hh:583
static constexpr T min(T a)
Definition: utility.hh:81
void adjustMemory(size_t mSize)
adjust the memory
Definition: arrays.hh:538
static void assign(ArrayType &array, const int newIndex, const int oldIndex)
Definition: arrays.hh:637
size_t usedMemorySize() const
return size of vector in bytes
Definition: arrays.hh:531
bool write(OutStreamInterface< StreamTraits > &out) const
write to stream
Definition: arrays.hh:342
T FieldType
Definition: arrays.hh:154
size_t size_
Definition: arrays.hh:150
void resize(size_t nsize)
Definition: arrays.hh:491
GenericIterator< const ThisType, const T > ConstDofIteratorType
Const DofIterator.
Definition: arrays.hh:168
bool operator==(const ThisType &other) const
Definition: arrays.hh:325
T * data()
return leak pointer for usage in BLAS routines
Definition: arrays.hh:336
size_t size_type
type of unsigned integral type of indexing
Definition: arrays.hh:174
static void free(T *p)
release memory previously allocated with malloc member
Definition: arrays.hh:89
Definition: arrays.hh:36
StaticArray(const size_t size, T *vec)
create array of length size and store vec as pointer to memory
Definition: arrays.hh:177
oriented to the STL Allocator funtionality
Definition: arrays.hh:33
void axpy(const ThisType &org, const T scalar)
axpy operation
Definition: arrays.hh:300
DofIteratorType begin()
iterator pointing to begin of array
Definition: arrays.hh:193
MutableArray()
create array of length 0
Definition: arrays.hh:437
StaticArray< T > ThisType
Definition: arrays.hh:144
static void memMoveBackward(ArrayType &array, const size_t length, const size_t oldStartIdx, const size_t newStartIdx)
Definition: arrays.hh:593
StaticArray< T > BaseType
Definition: arrays.hh:422
SpecialArrayFeatures is a wrapper class to extend some array classes with some special features neede...
Definition: arrays.hh:39
DofIteratorType end()
iterator pointing to end of array
Definition: arrays.hh:203
const T * leakPointer() const
return leak pointer for usage in BLAS routines
Definition: arrays.hh:333
static T * malloc(size_t nmemb)
allocate array of nmemb objects of type T
Definition: arrays.hh:47
static void free(T *p)
release memory previously allocated with malloc member
Definition: arrays.hh:56
T * vec_
Definition: arrays.hh:147
double memoryFactor_
Definition: arrays.hh:428
Definition: coordinate.hh:4
static size_t used(const ArrayType &array)
Definition: arrays.hh:584
T value_type
definition conforming to STL
Definition: arrays.hh:156
abstract interface for an input stream
Definition: streams.hh:177
Static Array Wrapper for simple C Vectors like double* and int*. This also works as base class for th...
Definition: arrays.hh:141
MutableArray< T, AllocatorType > ThisType
Definition: arrays.hh:421
void reserve(size_t mSize)
Definition: arrays.hh:517
T block_type
definition conforming to ISTL
Definition: arrays.hh:159
~MutableArray()
Destructor.
Definition: arrays.hh:471
size_t memSize_
Definition: arrays.hh:431
ConstDofIteratorType const_iterator
make compatible with std::vector
Definition: arrays.hh:171
void setMemoryFactor(const double memFactor)
set memory factor
Definition: arrays.hh:465
StaticArray(const size_t size, const T *vec)
create array of length size and store vec as pointer to memory
Definition: arrays.hh:185
T * leakPointer()
return leak pointer for usage in BLAS routines
Definition: arrays.hh:331
MutableArray(const MutableArray &other)
copy constructor
Definition: arrays.hh:445
Definition: arrays.hh:77
GenericIterator< ThisType, T > DofIteratorType
DofIterator.
Definition: arrays.hh:162
static T * malloc(size_t nmemb)
allocate array of nmemb objects of type T
Definition: arrays.hh:80
void freeMemory()
Definition: arrays.hh:567
ConstDofIteratorType begin() const
const iterator pointing to begin of array
Definition: arrays.hh:198
DofIteratorType iterator
make compatible with std::vector
Definition: arrays.hh:165
void memmove(const int length, const int oldStartIdx, const int newStartIdx)
move memory from old to new destination
Definition: arrays.hh:315
ConstDofIteratorType end() const
const iterator pointing to end of array
Definition: arrays.hh:208
static void memMoveForward(ArrayType &array, const size_t length, const size_t oldStartIdx, const size_t newStartIdx)
Definition: arrays.hh:615
static T * realloc(T *oldMem, size_t oldSize, size_t nmemb)
allocate array of nmemb objects of type T
Definition: arrays.hh:62
MutableArray(const size_t size)
create array of length size
Definition: arrays.hh:455
abstract interface for an output stream
Definition: streams.hh:44
const T * data() const
return leak pointer for usage in BLAS routines
Definition: arrays.hh:338