ElInfo.h 16.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  crystal growth group                                                  ==
// ==                                                                        ==
// ==  Stiftung caesar                                                       ==
// ==  Ludwig-Erhard-Allee 2                                                 ==
// ==  53175 Bonn                                                            ==
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  http://www.caesar.de/cg/AMDiS                                         ==
// ==                                                                        ==
// ============================================================================

/** \file ElInfo.h */

#ifndef AMDIS_ELINFO_H
#define AMDIS_ELINFO_H

// ============================================================================
// ===== includes =============================================================
// ============================================================================
#include "Flag.h"
#include "Boundary.h"
#include "Global.h"
#include "FixVec.h"
#include "Element.h"

namespace AMDiS {

  // ============================================================================
  // ===== forward declarations =================================================
  // ============================================================================
  class MacroElement;
  class Mesh;
  class Element;
  class BasisFunction;
  class Projection;
  template<typename ReturnType, typename ArgumentType> class AbstractFunction;


  // ============================================================================
  // ===== class ElInfo =========================================================
  // ============================================================================

  /** \ingroup Traverse
   * \brief 
   * An ElInfo object holds informations wich are not stored in the corresponding
   * element. It is filled during mesh traversal by the traversal routines.
   * A fill flag determines which informations should be filled and which elements
   * should be visited. Since it is a
   * pure virtual base class for the dimension speciefic ElInfo classes, it must
   * not be instantiated directly.
   * \see ElInfo1d \see ElInfo2d \see ElInfo3d
   */

  class ElInfo
  {
    // ===== construtors, destructors =============================================
  protected: 
    /** \brief
     * Protected constructor. Avoids instatiation of the basis class
     */
    ElInfo();

    /** \brief
     * Protected constructor. Avoids instatiation of the basis class.
     * \param mesh pointer to the corresponding mesh.
     */
    ElInfo(Mesh *mesh);

  public:
    /** \brief
     * Virtual destructor because ElInfo is pure virtual.
     */
    virtual ~ElInfo();

    /** \brief
     * Assignement operator.
     * \param rhs right hand side.
     */
    ElInfo& operator=(const ElInfo& rhs) {
      mesh_ = rhs.mesh_;
      element_ = rhs.element_;
      parent_ = rhs.parent_;
      macroElement_ = rhs.macroElement_;
      fillFlag_ = rhs.fillFlag_;
93
      level = rhs.level;
94
      iChild = rhs.iChild;
95
96
97
98
      coord_ = rhs.coord_;
      boundary_ = rhs.boundary_;
      oppCoord_ = rhs.oppCoord_;
      neighbour_ = rhs.neighbour_;
99
      neighbourCoord_ = rhs.neighbourCoord_;
100
101
      oppVertex_ = rhs.oppVertex_;
      return *this;
102
    }
103
104
105
106
107
108

  public:
    /** \name getting methods
     * \{ 
     */

109
    /// Get ElInfo's \ref mesh_
110
111
    inline Mesh* getMesh() const { 
      return mesh_; 
112
    }
113

114
    /// Get ElInfo's \ref macroElement_
115
116
    inline MacroElement* getMacroElement() const { 
      return macroElement_; 
117
    }
118

119
    /// Get ElInfo's \ref element
120
121
    inline Element* getElement() const { 
      return element_; 
122
    }
123

124
    /// Get ElInfo's \ref parent_
125
126
    inline Element* getParent() const { 
      return parent_; 
127
    }
128

129
    /// Get ElInfo's \ref fillFlag_
130
131
    inline Flag getFillFlag() const { 
      return fillFlag_; 
132
    }
133

134
    /// Get ElInfo's \ref level
135
136
137
138
    inline int getLevel() const { 
      return level; 
    }

139
    /// Get ElInfo's \ref iChild
140
141
    inline int getIChild() const {
      return iChild;
142
    }
143
144
145
146
147
148
149

    /** \brief
     * Get ElInfo's \ref coord_[i]. This is a WorldVector<double> filled with the
     * coordinates of the i-th vertex of element \ref el.
     */
    inline WorldVector<double>& getCoord(int i) { 
      return coord_[i]; 
150
    }
151
152
153
154
155
156
157

    /** \brief
     * Get ElInfo's \ref coord_[i]. This is a WorldVector<double> filled with the
     * coordinates of the i-th vertex of element \ref el.
     */
    inline const WorldVector<double>& getCoord(int i) const { 
      return coord_[i]; 
158
    }
159
160
161
162
163

    /** \brief
     * Get ElInfo's \ref coord_. This is a FixVec<WorldVector<double> > filled with the
     * coordinates of the all vertice of element \ref el.
     */
164
    inline FixVec<WorldVector<double>, VERTEX>& getCoords() { 
165
      return coord_; 
166
    }
167
168
169
170
171

    /** \brief
     * Get ElInfo's \ref coord_. This is a FixVec<WorldVector<double> > filled with the
     * coordinates of the all vertice of element \ref el.
     */
172
    inline const FixVec<WorldVector<double>, VERTEX>& getCoords() const { 
173
      return coord_; 
174
    }
175

176
    /// Get ElInfo's \ref oppCoord_[i]
177
178
    inline WorldVector<double>& getOppCoord(int i) { 
      return oppCoord_[i]; 
179
    }
180
181
182
183

    /** \brief
     * Get ElInfo's \ref boundary_[i] 
     */
184
    inline BoundaryType getBoundary(int i) const { 
185
      return boundary_[i]; 
186
    }
187
188
189
190
191
192
193
194
195
196
197

    /** \brief
     * Get boundary type of i-th vertex/edge/face (pos).
     */
    BoundaryType getBoundary(GeoIndex pos, int i);

    /** \brief
     * Get ElInfo's \ref neighbour_[i]
     */
    inline Element* getNeighbour(int i) const { 
      return neighbour_[i]; 
198
    }
199

200
201
202
203
204
205
206
    /** \brief
     * Get ElInfo's \ref neighbourCoord_[i]
     */
    inline FixVec<WorldVector<double>, VERTEX> getNeighbourCoord(int i) const {
      return neighbourCoord_[i];
    }

207
208
209
210
211
    /** \brief
     * Get ElInfo's \ref oppVertex_[i] 
     */
    inline unsigned char getOppVertex(int i) const { 
      return oppVertex_[i]; 
212
    }
213
214
215

    virtual int getSideOfNeighbour(int i) { 
      return oppVertex_[i]; 
216
    }
217
218
219
220
221
222

    /** \brief
     * Get ElInfo's \ref det_
     */
    inline double getDet() const { 
      return det_; 
223
    }
224
225

    /** \brief
Thomas Witkowski's avatar
Thomas Witkowski committed
226
     * Returns \ref grdLambda
227
228
     */
    inline const DimVec<WorldVector<double> >& getGrdLambda() const { 
Thomas Witkowski's avatar
Thomas Witkowski committed
229
      return grdLambda; 
230
    }
231
232
233
234
235
236

    /** \brief
     * Returns \ref projection_[i]
     */
    inline Projection *getProjection(int i) const {
      return projection_[i];
237
    }
238
239
240
241
242
243

    /** \brief
     * Returns \ref parametric_
     */
    inline bool getParametric() { 
      return parametric_; 
244
245
    }

246
247
248
249
250
251
    /** \brief
     * Returns the element transformation matrix \ref subElemCoordsMat .
     * This value is set only during dual traverse.
     */
    inline DimMat<double> *getSubElemCoordsMat() const {
      return subElemCoordsMat;
252
    }
253
254
255
256
257
258
259
260
261
262
263
264
265
266

    /** \} */ 

    // ===== setting-methods ======================================================

    /** \name setting methods
     * \{ 
     */

    /** \brief
     * Set ElInfo's \ref mesh_
     */
    inline void setMesh(Mesh* aMesh) { 
      mesh_ = aMesh; 
267
    }
268
269
270
271
272
273

    /** \brief
     * Set ElInfo's \ref macroElement_
     */
    inline void setMacroElement(MacroElement* mel) { 
      macroElement_ = mel; 
274
    }
275
276
277
278
279
280

    /** \brief
     * Set ElInfo's \ref element
     */
    inline void setElement(Element* elem) { 
      element_ = elem; 
281
    }
282
283
284
285
286
287

    /** \brief
     * Set ElInfo's \ref parent_
     */
    inline void setParent(Element* elem) { 
      parent_ = elem; 
288
    }
289
290
291
292
293
294

    /** \brief
     * Set ElInfo's \ref fillFlag_
     */
    inline void setFillFlag(Flag flag) { 
      fillFlag_ = flag; 
295
    }
296
297
298
299
300
301

    /** \brief
     * Sets ElInfo's \ref coord_[i]. 
     */
    inline void setCoord(int i,WorldVector<double>& coord) { 
      coord_[i] = coord; 
302
    }
303
304
305
306
307
308

    /** \brief
     * Sets ElInfo's \ref coord. 
     */
    inline void setCoords(FixVec<WorldVector<double>,VERTEX >& coords) { 
      coord_ = coords; 
309
    }
310
311

    /** \brief
312
     * Set ElInfo's \ref level
313
314
     */
    inline void setLevel(int l) { 
315
316
317
      level = l; 
    }

318
319
320
321
322
    /** \brief
     * Set ElInfo's \ref boundary_[i] 
     */
    inline void setBoundary(int i, BoundaryType t) { 
      boundary_[i] = newBound(boundary_[i], t);
323
    }
324
325
326
327
328
329

    /** \brief
     * Set \ref projection_[i] = p
     */
    inline void setProjection(int i, Projection *p) {
      projection_[i] = p;
330
    }
331
332
333
334
335
336

    /** \brief
     * Set \ref det_ = d
     */
    inline void setDet(double d) { 
      det_ = d; 
337
    }
338
339
340
341
342
343

    /** \brief
     * Set \ref parametric_ = param
     */
    inline void setParametric(bool param) { 
      parametric_ = param; 
344
345
    }

346
347
348
349
350
351
    /** \brief
     * Sets the element transformation matrix \ref subElemCoordsMat .
     * This value is used only during dual traverse.
     */
    inline void setSubElemCoordsMat(DimMat<double> *mat) {
      subElemCoordsMat = mat;
352
    }
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  
    /** \} */

    // ===== other public methods =================================================
  

    /** \brief
     * Returns the absolute value of the determinant of the affine linear 
     * parametrization's Jacobian
     */
    virtual double calcDet() const;

    /** \brief
     * Used by non static method \ref calcDet(). Calculates the determinant
     * for a given vector of vertex coordinates.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
369
    double calcDet(const FixVec<WorldVector<double>, VERTEX> &coords) const;
370
371
372
373
374
375
376
377

    /** \brief
     * Checks whether flag is set in ElInfo's \ref fillFlag_. If not, the program
     * exits.
     */
    void testFlag(const Flag& flag) const;

    /** \brief
378
379
     * Transforms local barycentric coordinates of a point defined on this element
     * to global world coordinates.
380
     */
381
382
    void coordToWorld(const DimVec<double>& lambda,
		      WorldVector<double>& world) const;
383
384
385
  

    /** \brief
Thomas Witkowski's avatar
Thomas Witkowski committed
386
     * Fills ElInfo's \ref det_ and \ref grdLambda entries.
387
388
389
390
391
392
393
394
395
396
397
398
     */
    virtual void fillDetGrdLambda();

    // ===== pure virtual functions. Must be overriden in sub-classes ============

    /** \brief
     * Returns a pointer to a vector, which contains the barycentric coordinates
     * with respect to \ref element of a point with world coordinates world.
     * The barycentric coordinates are stored in lambda. 
     * pure virtual => must be overriden in sub-class.
     */
    virtual const int worldToCoord(const WorldVector<double>& world, 
399
				   DimVec<double>* lambda) const = 0;
400
401
402
403
404
405
406
407
408
409
410
411

    /** \brief
     * Fills this ElInfo with macro element information of mel.
     * pure virtual => must be overriden in sub-class.
     */
    virtual void fillMacroInfo(const MacroElement *mel) = 0;

    /** \brief
     * Fills this ElInfo for the child ichild using hierarchy information and
     * parent data parentInfo.
     * pure virtual => must be overriden in sub-class.
     */
412
    virtual void fillElInfo(int ichild, const ElInfo *parentInfo) = 0;
413
414
415
416
417
418
419

    /** \brief
     * calculates the Jacobian of the barycentric coordinates on \element and stores
     * the matrix in grd_lam. The return value of the function is the absolute
     * value of the determinant of the affine linear paraetrization's Jacobian.
     * pure virtual => must be overriden in sub-class.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
420
    virtual double calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) = 0;
421
422
423
424
425
426
427

    /** \brief
     * calculates a normal of the given side (1d,2d: edge, 3d: face) of \ref element.
     * Returns the absolute value of the determinant of the
     * transformation to the reference element.
     * pure virtual => must be overriden in sub-class.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
428
    virtual double getNormal(int side, WorldVector<double> &normal) = 0;
429
430
431
432
433
434
435
436
437
438


    /** \brief
     * calculates a normal of the element in dim of world = dim + 1.
     * Returns the absolute value of the determinant of the
     * transformation to the reference element.
     * pure virtual => must be overriden in sub-class.
     */
    virtual double getElementNormal(WorldVector<double> &elementNormal) const 
    {
439
440
      FUNCNAME("ElInfo::getElementNormal()");

441
442
443
      ERROR("virtual function not implemented in this sub-class ");
    
      return(0.0);
444
    }
445

446
    virtual void getRefSimplexCoords(DimMat<double> *coords) const = 0;
447

448
    virtual void getSubElementCoords(DimMat<double> *coords,
449
				     int iChild) const = 0;
450
451

  protected:
452
    /// Pointer to the current mesh
453
454
    Mesh *mesh_;

455
    /// Pointer to the current element
456
457
    Element *element_;

458
    /// \ref element is child of element parent_
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
    Element *parent_;

    /** \brief 
     * \ref element is an element of the binary tree located at MacroElement 
     * macroElement_
     */
    MacroElement *macroElement_;

    /** \brief
     * Indicates wich elements will be called and wich information should be
     * present while mesh traversal.
     */
    Flag fillFlag_;

    /** \brief 
     * Level of the element. The level is zero for macro elements and the level
     * of the children is (level of the parent + 1). level_ is filled always by
     * the traversal routines.
     */
478
479
    unsigned char level;

480
481
482
483
484
    /** \brief
     * This ElInfo is the iChild-th child of the parent element.
     */
    int iChild;

485
486
487
488
    /** \brief 
     * \ref coord_[i] is a WorldVector<double> storing the world coordinates of the
     * i-th vertex of element \ref element.
     */
489
    FixVec<WorldVector<double>, VERTEX> coord_;
490
491
492
493
494
495
496
497

    /** \brief 
     * boundary_[i] is the BoundaryType of the i-th edge/face
     * for i=0,...,N_NEIGH - 1. In 3d 
     * (*boundary_)[N_FACES + i] is a pointer to the Boundary
     * object of the i-th edge, for i=0,..,N_EDGES - 1. It is
     * a pointer to NULL for an interior edge/face.
     */
498
    FixVec<BoundaryType, BOUNDARY> boundary_;
499
500
501
502
503
504
505
506
507
508

    /** \brief
     * Vector storing pointers to projections for each face, edge, vertex.
     */
    FixVec<Projection*, PROJECTION> projection_;

    /** \brief 
     * oppCoord_[i] coordinates of the i-th neighbour vertex opposite the
     * common edge/face.
     */
509
    FixVec<WorldVector<double>, NEIGH> oppCoord_;
510
511
512
513
514

    /** \brief 
     * neighbour_[i] pointer to the element at the edge/face with local index i.
     * It is a pointer to NULL for boundary edges/faces.
     */
515
516
517
518
519
520
521
    FixVec<Element*, NEIGH> neighbour_;

    /** \brief
     * neighbourCoord_[i][j] are the coordinate of the j-th vertex of the i-th
     * neighbour element with the common edge/face.
     */
    FixVec<FixVec<WorldVector<double>, VERTEX>, NEIGH> neighbourCoord_;
522
523
524
525
526
527

    /** \brief 
     * oppVertex_[i] is undefined if neighbour_[i] is a pointer to NULL. 
     * Otherwise it is the local index of the neighbour's vertex opposite the
     * common edge/face.
     */
528
    FixVec<unsigned char, NEIGH> oppVertex_;
529

Thomas Witkowski's avatar
Thomas Witkowski committed
530
    /// Elements determinant.
531
532
    double det_;

Thomas Witkowski's avatar
Thomas Witkowski committed
533
    /// Gradient of lambda.
Thomas Witkowski's avatar
Thomas Witkowski committed
534
    DimVec<WorldVector<double> > grdLambda;
535

Thomas Witkowski's avatar
Thomas Witkowski committed
536
    /// True, if this elInfo stores parametrized information. False, otherwise.
537
538
    bool parametric_;

Thomas Witkowski's avatar
Thomas Witkowski committed
539
    /// Stores the world dimension.
Thomas Witkowski's avatar
Thomas Witkowski committed
540
541
    int dimOfWorld;

542
543
544
545
546
547
548
549
    /** \brief
     * This is a transformation matrix used during dual traverse. It is set, if
     * the current element is the smaller element of an element pair in the traverse.
     * Then this matrix defines a mapping for points defined in barycentric 
     * coordinates on the larger element, to the barycentric coordinates of the smaller
     * element.
     */
    DimMat<double> *subElemCoordsMat;
550

551
552
553
554
555
556
557
558
559
    // ===== static public members ================================================
  public:
    /** \brief 
     * child_vertex[el_type][child][i] = father's local vertex index of new 
     * vertex i. 4 stands for the newly generated vertex .
     */
    static const int childVertex[3][2][4];

    /** \brief 
560
     * child_edge[el_type][child][i] = father's local edge index of new edge i.
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
     * new edge 2 is half of old edge 0, new edges 4,5 are really new edges, and
     * value is different: child_edge[][][4,5] = index of same edge in other
     * child.
     */
    static const int childEdge[3][2][6];

    friend class ElInfo1d;
    friend class ElInfo2d;
    friend class ElInfo3d;
  };

}

#include "ElInfo1d.h"
#include "ElInfo2d.h"
#include "ElInfo3d.h"

#endif  // AMDIS_ELINFO_H