Dune Core Modules (2.6.0)

macrodata.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_ALBERTA_MACRODATA_HH
4 #define DUNE_ALBERTA_MACRODATA_HH
5 
11 #include <dune/common/fvector.hh>
12 #include <dune/common/fmatrix.hh>
13 
14 #include <dune/grid/albertagrid/misc.hh>
15 #include <dune/grid/albertagrid/algebra.hh>
16 #include <dune/grid/albertagrid/albertaheader.hh>
17 
18 #if HAVE_ALBERTA
19 
20 namespace Dune
21 {
22 
23  namespace Alberta
24  {
25 
26  template< int dim >
27  class MacroData
28  {
29  typedef MacroData< dim > This;
30 
31  typedef ALBERTA MACRO_DATA Data;
32 
33  static const int dimension = dim;
34  static const int numVertices = NumSubEntities< dimension, dimension >::value;
35  static const int numEdges = NumSubEntities< dimension, dimension-1 >::value;
36 
37  static const int initialSize = 4096;
38 
39  public:
40  template< int >
41  struct Library;
42 
43  template< int > friend struct InstantiateMacroDataLibrary;
44 
45  public:
46  typedef int ElementId[ numVertices ];
47 
48  static const int supportPeriodicity = 1;
49 
50  MacroData ()
51  : data_( NULL ),
52  vertexCount_( -1 ),
53  elementCount_( -1 )
54  {}
55 
56  operator Data * () const
57  {
58  return data_;
59  }
60 
61  int vertexCount () const
62  {
63  return (vertexCount_ < 0 ? data_->n_total_vertices : vertexCount_);
64  }
65 
66  int elementCount () const
67  {
68  return (elementCount_ < 0 ? data_->n_macro_elements : elementCount_);
69  }
70 
71  ElementId &element ( int i ) const;
72  GlobalVector &vertex ( int i ) const;
73  int &neighbor ( int element, int i ) const;
74  BoundaryId &boundaryId ( int element, int i ) const;
75 
80  void create ();
81 
90  void finalize ();
91 
100  void markLongestEdge ();
101 
110  void setOrientation ( const Real orientation );
111 
122  bool checkNeighbors () const;
123 
125  void release ()
126  {
127  if( data_ != NULL )
128  {
129  ALBERTA free_macro_data( data_ );
130  data_ = NULL;
131  }
132  vertexCount_ = elementCount_ = -1;
133  }
134 
140  int insertElement ( const ElementId &id );
141 
147  int insertVertex ( const GlobalVector &coords )
148  {
149  assert( vertexCount_ >= 0 );
150  if( vertexCount_ >= data_->n_total_vertices )
151  resizeVertices( 2*vertexCount_ );
152  copy( coords, vertex( vertexCount_ ) );
153  return vertexCount_++;
154  }
155 
161  int insertVertex ( const FieldVector< Real, dimWorld > &coords )
162  {
163  assert( vertexCount_ >= 0 );
164  if( vertexCount_ >= data_->n_total_vertices )
165  resizeVertices( 2*vertexCount_ );
166  copy( coords, vertex( vertexCount_ ) );
167  return vertexCount_++;
168  }
169 
170  void insertWallTrafo ( const GlobalMatrix &m, const GlobalVector &t );
171  void insertWallTrafo ( const FieldMatrix< Real, dimWorld, dimWorld > &matrix,
172  const FieldVector< Real, dimWorld > &shift );
173 
174  void checkCycles ();
175 
176  void read ( const std::string &filename, bool binary = false );
177 
178  bool write ( const std::string &filename, bool binary = false ) const
179  {
180  if( binary )
181  return ALBERTA write_macro_data_xdr( data_, filename.c_str() );
182  else
183  return ALBERTA write_macro_data( data_, filename.c_str() );
184  }
185 
186  private:
187  template< class Vector >
188  void copy ( const Vector &x, GlobalVector &y )
189  {
190  for( int i = 0; i < dimWorld; ++i )
191  y[ i ] = x[ i ];
192  }
193 
194  void resizeElements ( const int newSize );
195 
196  void resizeVertices ( const int newSize )
197  {
198  const int oldSize = data_->n_total_vertices;
199  data_->n_total_vertices = newSize;
200  data_->coords = memReAlloc< GlobalVector >( data_->coords, oldSize, newSize );
201  assert( (data_->coords != NULL) || (newSize == 0) );
202  }
203 
204  private:
205  Data *data_;
206  int vertexCount_;
207  int elementCount_;
208  };
209 
210 
211 
212  // MacroData::Library
213  // ------------------
214 
215  template< int dim >
216  template< int >
217  struct MacroData< dim >::Library
218  {
219  typedef Alberta::MacroData< dim > MacroData;
220 
221  static bool checkNeighbors ( const MacroData &macroData );
222  static void markLongestEdge ( MacroData &macroData );
223  static void setOrientation ( MacroData &macroData, const Real orientation );
224 
225  private:
226  static Real edgeLength ( const MacroData &macroData, const ElementId &e, int edge );
227  static int longestEdge ( const MacroData &macroData, const ElementId &e );
228 
229  template< class Type >
230  static void rotate ( Type *array, int i, int shift );
231 
232  static void rotate ( MacroData &macroData, int i, int shift );
233  static void swap ( MacroData &macroData, int el, int v1, int v2 );
234  };
235 
236 
237 
238  // Implementation of MacroData
239  // ---------------------------
240 
241  template< int dim >
242  inline typename MacroData< dim >::ElementId &
243  MacroData< dim >::element ( int i ) const
244  {
245  assert( (i >= 0) && (i < data_->n_macro_elements) );
246  const int offset = i * numVertices;
247  return *reinterpret_cast< ElementId * >( data_->mel_vertices + offset );
248  }
249 
250 
251  template< int dim >
252  inline GlobalVector &MacroData< dim >::vertex ( int i ) const
253  {
254  assert( (i >= 0) && (i < data_->n_total_vertices) );
255  return data_->coords[ i ];
256  }
257 
258 
259  template< int dim >
260  inline int &MacroData< dim >::neighbor ( int element, int i ) const
261  {
262  assert( (element >= 0) && (element < data_->n_macro_elements) );
263  assert( (i >= 0) && (i < numVertices) );
264  return data_->neigh[ element*numVertices + i ];
265  }
266 
267 
268  template< int dim >
269  inline BoundaryId &MacroData< dim >::boundaryId ( int element, int i ) const
270  {
271  assert( (element >= 0) && (element < data_->n_macro_elements) );
272  assert( (i >= 0) && (i < numVertices) );
273  return data_->boundary[ element*numVertices + i ];
274  }
275 
276 
277  template< int dim >
278  inline void MacroData< dim >::create ()
279  {
280  release();
281  data_ = ALBERTA alloc_macro_data( dim, initialSize, initialSize );
282  data_->boundary = memAlloc< BoundaryId >( initialSize*numVertices );
283  if( dim == 3 )
284  data_->el_type = memAlloc< ElementType >( initialSize );
285  vertexCount_ = elementCount_ = 0;
286  elementCount_ = 0;
287  }
288 
289 
290  template< int dim >
291  inline void MacroData< dim >::finalize ()
292  {
293  if( (vertexCount_ >= 0) && (elementCount_ >= 0) )
294  {
295  resizeVertices( vertexCount_ );
296  resizeElements( elementCount_ );
297  ALBERTA compute_neigh_fast( data_ );
298 
299  // assign default boundary id (if none is assigned)
300  for( int element = 0; element < elementCount_; ++element )
301  {
302  for( int i = 0; i < numVertices; ++i )
303  {
304  BoundaryId &id = boundaryId( element, i );
305  if( neighbor( element, i ) >= 0 )
306  {
307  assert( id == InteriorBoundary );
308  id = InteriorBoundary;
309  }
310  else
311  id = (id == InteriorBoundary ? DirichletBoundary : id);
312  }
313  }
314 
315  vertexCount_ = elementCount_ = -1;
316  }
317  assert( (vertexCount_ < 0) && (elementCount_ < 0) );
318  }
319 
320 
321  template< int dim >
322  inline void MacroData< dim >::markLongestEdge ()
323  {
324  Library< dimWorld >::markLongestEdge( *this );
325  }
326 
327 
328  template< int dim >
329  inline void MacroData< dim >::setOrientation ( const Real orientation )
330  {
331  Library< dimWorld >::setOrientation( *this, orientation );
332  }
333 
334 
335  template< int dim >
336  inline bool MacroData< dim >::checkNeighbors () const
337  {
338  return Library< dimWorld >::checkNeighbors( *this );
339  }
340 
341 
342  template< int dim >
343  inline int MacroData< dim >::insertElement ( const ElementId &id )
344  {
345  assert( elementCount_ >= 0 );
346  if( elementCount_ >= data_->n_macro_elements )
347  resizeElements( 2*elementCount_ );
348 
349  ElementId &e = element( elementCount_ );
350  for( int i = 0; i < numVertices; ++i )
351  {
352  e[ i ] = id[ i ];
353  boundaryId( elementCount_, i ) = InteriorBoundary;
354  }
355  if( dim == 3 )
356  data_->el_type[ elementCount_ ] = 0;
357 
358  return elementCount_++;
359  }
360 
361 
362  template< int dim >
363  inline void MacroData< dim >
364  ::insertWallTrafo ( const GlobalMatrix &matrix, const GlobalVector &shift )
365  {
366  int &count = data_->n_wall_trafos;
367  AffineTransformation *&array = data_->wall_trafos;
368 
369  // resize wall trafo array
370  array = memReAlloc< AffineTransformation >( array, count, count+1 );
371  assert( data_->wall_trafos != NULL );
372 
373  // copy matrix and shift
374  for( int i = 0; i < dimWorld; ++i )
375  copy( matrix[ i ], array[ count ].M[ i ] );
376  copy( shift, array[ count ].t );
377  ++count;
378  }
379 
380  template< int dim >
381  inline void MacroData< dim >
382  ::insertWallTrafo ( const FieldMatrix< Real, dimWorld, dimWorld > &matrix,
383  const FieldVector< Real, dimWorld > &shift )
384  {
385  int &count = data_->n_wall_trafos;
386  AffineTransformation *&array = data_->wall_trafos;
387 
388  // resize wall trafo array
389  array = memReAlloc< AffineTransformation >( array, count, count+1 );
390  assert( data_->wall_trafos != NULL );
391 
392  // copy matrix and shift
393  for( int i = 0; i < dimWorld; ++i )
394  copy( matrix[ i ], array[ count ].M[ i ] );
395  copy( shift, array[ count ].t );
396  ++count;
397  }
398 
399 
400  template< int dim >
401  inline void MacroData< dim >::checkCycles ()
402  {
403  // ensure that the macro data has been finalized
404  finalize();
405  ALBERTA macro_test( data_, NULL );
406  }
407 
408 
409  template< int dim >
410  inline void MacroData< dim >::read ( const std::string &filename, bool binary )
411  {
412  release();
413  if( binary )
414  data_ = ALBERTA read_macro_xdr( filename.c_str() );
415  else
416  data_ = ALBERTA read_macro( filename.c_str() );
417  }
418 
419 
420  template< int dim >
421  inline void MacroData< dim >::resizeElements ( const int newSize )
422  {
423  const int oldSize = data_->n_macro_elements;
424  data_->n_macro_elements = newSize;
425  data_->mel_vertices = memReAlloc( data_->mel_vertices, oldSize*numVertices, newSize*numVertices );
426  data_->boundary = memReAlloc( data_->boundary, oldSize*numVertices, newSize*numVertices );
427  if( dim == 3 )
428  data_->el_type = memReAlloc( data_->el_type, oldSize, newSize );
429  assert( (newSize == 0) || (data_->mel_vertices != NULL) );
430  }
431 
432  }
433 
434 }
435 
436 #endif // #if HAVE_ALBERTA
437 
438 #endif
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:727
Dune namespace.
Definition: alignedallocator.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)