ElInfo.h 15.4 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
// ============================================================================
// ==                                                                        ==
// == 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

25
26
#include <boost/numeric/mtl/mtl.hpp>

27
28
29
30
31
#include "Flag.h"
#include "Boundary.h"
#include "Global.h"
#include "FixVec.h"
#include "Element.h"
32
#include "AMDiS_fwd.h" 
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

namespace AMDiS {

  /** \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
  {
  protected: 
50
    /// Protected constructor. Avoids instatiation of the basis class
51
52
53
54
55
56
57
58
59
    ElInfo();

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

  public:
60
    /// Virtual destructor because ElInfo is pure virtual.
61
62
63
64
65
66
67
68
69
70
71
72
    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_;
73
      level = rhs.level;
74
      iChild = rhs.iChild;
75
76
77
78
      coord_ = rhs.coord_;
      boundary_ = rhs.boundary_;
      oppCoord_ = rhs.oppCoord_;
      neighbour_ = rhs.neighbour_;
79
      neighbourCoord_ = rhs.neighbourCoord_;
80
81
      oppVertex_ = rhs.oppVertex_;
      return *this;
82
    }
83
84
85
86
87
88

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

89
    /// Get ElInfo's \ref mesh_
90
91
    inline Mesh* getMesh() const { 
      return mesh_; 
92
    }
93

94
    /// Get ElInfo's \ref macroElement_
95
96
    inline MacroElement* getMacroElement() const { 
      return macroElement_; 
97
    }
98

99
    /// Get ElInfo's \ref element
100
101
    inline Element* getElement() const { 
      return element_; 
102
    }
103

104
    /// Get ElInfo's \ref parent_
105
106
    inline Element* getParent() const { 
      return parent_; 
107
    }
108

109
    /// Get ElInfo's \ref fillFlag_
110
111
    inline Flag getFillFlag() const { 
      return fillFlag_; 
112
    }
113

114
    /// Get ElInfo's \ref level
115
116
117
118
    inline int getLevel() const { 
      return level; 
    }

119
    /// Get ElInfo's \ref iChild
120
121
    inline int getIChild() const {
      return iChild;
122
    }
123
124
125
126
127
128
129

    /** \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]; 
130
    }
131
132
133
134
135
136
137

    /** \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]; 
138
    }
139
140
141
142
143

    /** \brief
     * Get ElInfo's \ref coord_. This is a FixVec<WorldVector<double> > filled with the
     * coordinates of the all vertice of element \ref el.
     */
144
    inline FixVec<WorldVector<double>, VERTEX>& getCoords() { 
145
      return coord_; 
146
    }
147
148
149
150
151

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

156
    /// Get ElInfo's \ref oppCoord_[i]
157
158
    inline WorldVector<double>& getOppCoord(int i) { 
      return oppCoord_[i]; 
159
    }
160

161
    /// Get ElInfo's \ref boundary_[i] 
162
    inline BoundaryType getBoundary(int i) const { 
163
      return boundary_[i]; 
164
    }
165

166
    /// Get boundary type of i-th vertex/edge/face (pos).
167
168
    BoundaryType getBoundary(GeoIndex pos, int i);

169
    /// Get ElInfo's \ref neighbour_[i]
170
171
    inline Element* getNeighbour(int i) const { 
      return neighbour_[i]; 
172
    }
173

174
    /// Get ElInfo's \ref neighbourCoord_[i]
175
176
177
178
    inline FixVec<WorldVector<double>, VERTEX> getNeighbourCoord(int i) const {
      return neighbourCoord_[i];
    }

179
    /// Get ElInfo's \ref oppVertex_[i] 
180
181
    inline unsigned char getOppVertex(int i) const { 
      return oppVertex_[i]; 
182
    }
183
184
185

    virtual int getSideOfNeighbour(int i) { 
      return oppVertex_[i]; 
186
    }
187

188
    /// Get ElInfo's \ref det_
189
190
    inline double getDet() const { 
      return det_; 
191
    }
192

193
    /// Returns \ref grdLambda
194
    inline const DimVec<WorldVector<double> >& getGrdLambda() const { 
Thomas Witkowski's avatar
Thomas Witkowski committed
195
      return grdLambda; 
196
    }
197

198
    /// Returns \ref projection_[i]
199
200
    inline Projection *getProjection(int i) const {
      return projection_[i];
201
    }
202

203
    /// Returns \ref parametric_
204
205
    inline bool getParametric() { 
      return parametric_; 
206
207
    }

208
209
210
211
212
213
    /** \brief
     * Returns the element transformation matrix \ref subElemCoordsMat .
     * This value is set only during dual traverse.
     */
    inline DimMat<double> *getSubElemCoordsMat() const {
      return subElemCoordsMat;
214
    }
215

216
217
218
219
    inline mtl::dense2D<double>& getSubElemCoordsMat_mtl4() {
      return subElemCoordsMat_mtl;
    }

220
221
222
223
224
225
    /** \} */ 

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

226
    /// Set ElInfo's \ref mesh_
227
228
    inline void setMesh(Mesh* aMesh) { 
      mesh_ = aMesh; 
229
    }
230

231
    /// Set ElInfo's \ref macroElement_
232
233
    inline void setMacroElement(MacroElement* mel) { 
      macroElement_ = mel; 
234
    }
235

236
    /// Set ElInfo's \ref element
237
238
    inline void setElement(Element* elem) { 
      element_ = elem; 
239
    }
240

241
    /// Set ElInfo's \ref parent_
242
243
    inline void setParent(Element* elem) { 
      parent_ = elem; 
244
    }
245

246
    /// Set ElInfo's \ref fillFlag_
247
248
    inline void setFillFlag(Flag flag) { 
      fillFlag_ = flag; 
249
    }
250

251
    /// Sets ElInfo's \ref coord_[i]. 
252
253
    inline void setCoord(int i,WorldVector<double>& coord) { 
      coord_[i] = coord; 
254
    }
255

256
    /// Sets ElInfo's \ref coord. 
257
258
    inline void setCoords(FixVec<WorldVector<double>,VERTEX >& coords) { 
      coord_ = coords; 
259
    }
260

261
    /// Set ElInfo's \ref level
262
    inline void setLevel(int l) { 
263
264
265
      level = l; 
    }

266
    /// Set ElInfo's \ref boundary_[i] 
267
268
    inline void setBoundary(int i, BoundaryType t) { 
      boundary_[i] = newBound(boundary_[i], t);
269
    }
270

271
    /// Set \ref projection_[i] = p
272
273
    inline void setProjection(int i, Projection *p) {
      projection_[i] = p;
274
    }
275

276
    /// Set \ref det_ = d
277
278
    inline void setDet(double d) { 
      det_ = d; 
279
    }
280

281
    /// Set \ref parametric_ = param
282
283
    inline void setParametric(bool param) { 
      parametric_ = param; 
284
285
    }

286
287
288
289
290
291
    /** \brief
     * Sets the element transformation matrix \ref subElemCoordsMat .
     * This value is used only during dual traverse.
     */
    inline void setSubElemCoordsMat(DimMat<double> *mat) {
      subElemCoordsMat = mat;
292
    }
293
294
295
296
297
298
299
300
301
302
303
304
305
306
  
    /** \} */


    /** \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
307
    double calcDet(const FixVec<WorldVector<double>, VERTEX> &coords) const;
308
309
310
311
312
313
314
315

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

    /** \brief
316
317
     * Transforms local barycentric coordinates of a point defined on this element
     * to global world coordinates.
318
     */
319
320
    void coordToWorld(const DimVec<double>& lambda,
		      WorldVector<double>& world) const;
321
  
322
    /// Fills ElInfo's \ref det_ and \ref grdLambda entries.
323
324
325
326
327
328
329
330
331
    virtual void fillDetGrdLambda();

    /** \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, 
332
				   DimVec<double>* lambda) const = 0;
333
334
335
336
337
338
339
340
341
342
343
344

    /** \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.
     */
345
    virtual void fillElInfo(int ichild, const ElInfo *parentInfo) = 0;
346
347
348
349
350
351
352

    /** \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
353
    virtual double calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) = 0;
354
355
356
357
358
359
360

    /** \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
361
    virtual double getNormal(int side, WorldVector<double> &normal) = 0;
362
363
364
365
366
367
368
369
370
371


    /** \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 
    {
372
373
      FUNCNAME("ElInfo::getElementNormal()");

374
375
376
      ERROR("virtual function not implemented in this sub-class ");
    
      return(0.0);
377
    }
378

379
380
    virtual void getRefSimplexCoords(const BasisFunction *basisFcts,
				     DimMat<double> *coords) const = 0;
381

382
383
384
    virtual void getRefSimplexCoords(const BasisFunction *basisFcts,
				     mtl::dense2D<double>& coords) const = 0;

385
386
387
    virtual void getSubElementCoords(const BasisFunction *basisFcts,
				     int iChild,
				     DimMat<double> *coords) const = 0;
388

389
390
391
392
393
    virtual void getSubElementCoords(const BasisFunction *basisFcts,
				     int iChild,
				     mtl::dense2D<double>& coords) const = 0;


394
  protected:
395
    /// Pointer to the current mesh
396
397
    Mesh *mesh_;

398
    /// Pointer to the current element
399
400
    Element *element_;

401
    /// \ref element is child of element parent_
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    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.
     */
421
422
    unsigned char level;

423
424
425
426
427
    /** \brief
     * This ElInfo is the iChild-th child of the parent element.
     */
    int iChild;

428
429
430
431
    /** \brief 
     * \ref coord_[i] is a WorldVector<double> storing the world coordinates of the
     * i-th vertex of element \ref element.
     */
432
    FixVec<WorldVector<double>, VERTEX> coord_;
433
434
435
436
437
438
439
440

    /** \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.
     */
441
    FixVec<BoundaryType, BOUNDARY> boundary_;
442
443
444
445
446
447
448
449
450
451

    /** \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.
     */
452
    FixVec<WorldVector<double>, NEIGH> oppCoord_;
453
454
455
456
457

    /** \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.
     */
458
459
460
461
462
463
464
    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_;
465
466
467
468
469
470

    /** \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.
     */
471
    FixVec<unsigned char, NEIGH> oppVertex_;
472

Thomas Witkowski's avatar
Thomas Witkowski committed
473
    /// Elements determinant.
474
475
    double det_;

Thomas Witkowski's avatar
Thomas Witkowski committed
476
    /// Gradient of lambda.
Thomas Witkowski's avatar
Thomas Witkowski committed
477
    DimVec<WorldVector<double> > grdLambda;
478

Thomas Witkowski's avatar
Thomas Witkowski committed
479
    /// True, if this elInfo stores parametrized information. False, otherwise.
480
481
    bool parametric_;

Thomas Witkowski's avatar
Thomas Witkowski committed
482
    /// Stores the world dimension.
Thomas Witkowski's avatar
Thomas Witkowski committed
483
484
    int dimOfWorld;

485
486
487
488
489
490
491
492
    /** \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;
493

494
495
    mtl::dense2D<double> subElemCoordsMat_mtl;

496
497
498
499
500
501
502
503
  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 
504
     * child_edge[el_type][child][i] = father's local edge index of new edge i.
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
     * 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