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