Mesh.h 25.9 KB
Newer Older
1
2
3
4
5
6
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
7
// ==  TU Dresden                                                            ==
8
// ==                                                                        ==
9
10
11
// ==  Institut für Wissenschaftliches Rechnen                               ==
// ==  Zellescher Weg 12-14                                                  ==
// ==  01069 Dresden                                                         ==
12
13
14
15
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
16
// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// ==                                                                        ==
// ============================================================================

/** \file Mesh.h */

/** \defgroup Triangulation Triangulation module
 * @{ <img src="triangulation.png"> @}
 *
 * Example:
 *
 * @{ <img src="hierarchicalMesh.png"> @}
 *
 * \brief
 * Contains all triangulation classes.
 */

#ifndef AMDIS_MESH_H
#define AMDIS_MESH_H

Thomas Witkowski's avatar
Thomas Witkowski committed
36
37
38
39
#include <deque>
#include <set>
#include <stdio.h>
#include "AMDiS_fwd.h"
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include "DOFAdmin.h"
#include "Line.h"
#include "Triangle.h"
#include "Tetrahedron.h"
#include "Element.h"
#include "ElInfo.h"
#include "FixVec.h"
#include "Serializable.h"
#include "BoundaryCondition.h"

namespace AMDiS {

  /** \ingroup Triangulation 
   * \brief
   * A Mesh holds all information about a triangulation. 
   */
  class Mesh : public Serializable
  {
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
59
    /// Creates a mesh with the given name of dimension dim
Thomas Witkowski's avatar
Thomas Witkowski committed
60
    Mesh(std::string name, int dim);
61

Thomas Witkowski's avatar
Thomas Witkowski committed
62
    /// Destructor
63
64
    virtual ~Mesh();

Thomas Witkowski's avatar
Thomas Witkowski committed
65
    /// Reads macro triangulation.
66
67
    void initialize();

Thomas Witkowski's avatar
Thomas Witkowski committed
68
    /// Assignment operator
69
70
71
72
73
74
75
76
    Mesh& operator=(const Mesh&);

    /** \name getting methods
     * \{
     */

    /** \brief
     * Returns geometric information about this mesh. With GeoIndex p it is 
Backofen, Rainer's avatar
Backofen, Rainer committed
77
     * specified which information is requested.
78
     */
79
80
    inline int getGeo(GeoIndex p) const 
    { 
81
      return Global::getGeo(p, dim); 
82
    }
83

Thomas Witkowski's avatar
Thomas Witkowski committed
84
    /// Returns \ref name of the mesh
Thomas Witkowski's avatar
Thomas Witkowski committed
85
    inline std::string getName() const 
86
    { 
87
      return name; 
88
    }
89

Thomas Witkowski's avatar
Thomas Witkowski committed
90
    /// Returns \ref dim of the mesh
91
    inline int getDim() const
92
    { 
93
      return dim; 
94
    }
95

Thomas Witkowski's avatar
Thomas Witkowski committed
96
    /// Returns \ref nDOFEl of the mesh
97
98
    inline const int getNumberOfAllDOFs() const 
    { 
99
      return nDOFEl; 
100
    }
101

Thomas Witkowski's avatar
Thomas Witkowski committed
102
    /// Returns \ref nNodeEl of the mesh
103
104
    inline const int getNumberOfNodes() const 
    { 
105
      return nNodeEl; 
106
    }
107

Thomas Witkowski's avatar
Thomas Witkowski committed
108
    /// Returns \ref nVertices of the mesh
109
110
    inline const int getNumberOfVertices() const 
    { 
111
      return nVertices; 
112
    }
113

Thomas Witkowski's avatar
Thomas Witkowski committed
114
    /// Returns \ref nEdges of the mesh 
115
116
    inline const int getNumberOfEdges() const 
    { 
117
      return nEdges; 
118
    }
119

Thomas Witkowski's avatar
Thomas Witkowski committed
120
    /// Returns \ref nFaces of the mesh 
121
122
    inline const int getNumberOfFaces() const 
    { 
123
      return nFaces; 
124
    }
125

Thomas Witkowski's avatar
Thomas Witkowski committed
126
    /// Returns \ref nLeaves of the mesh 
127
128
    inline const int getNumberOfLeaves() const 
    { 
129
      return nLeaves; 
130
    }
131

Thomas Witkowski's avatar
Thomas Witkowski committed
132
    /// Returns \ref nElements of the mesh
133
134
    inline const int getNumberOfElements() const 
    { 
135
      return nElements; 
136
    }
137

Thomas Witkowski's avatar
Thomas Witkowski committed
138
    /// Returns \ref maxEdgeNeigh of the mesh
139
140
    inline const int getMaxEdgeNeigh() const 
    { 
141
      return maxEdgeNeigh; 
142
    }
143

Thomas Witkowski's avatar
Thomas Witkowski committed
144
    /// Returns \ref parametric of the mesh
145
146
    inline Parametric *getParametric() const 
    { 
147
      return parametric; 
148
    }
149

Thomas Witkowski's avatar
Thomas Witkowski committed
150
    /// Returns \ref diam of the mesh
151
152
    inline const WorldVector<double>& getDiameter() const 
    { 
153
      return diam; 
154
    }
155

Thomas Witkowski's avatar
Thomas Witkowski committed
156
    /// Returns nDOF[i] of the mesh
157
158
    inline const int getNumberOfDOFs(int i) const 
    { 
159
      return nDOF[i]; 
160
    }
161

Thomas Witkowski's avatar
Thomas Witkowski committed
162
    /// Returns \ref elementPrototype of the mesh
163
164
    inline Element* getElementPrototype() 
    { 
165
      return elementPrototype; 
166
    }
167

Thomas Witkowski's avatar
Thomas Witkowski committed
168
    /// Returns \ref leafDataPrototype of the mesh
169
170
    inline ElementData* getElementDataPrototype() 
    { 
171
      return elementDataPrototype; 
172
    }
173

Thomas Witkowski's avatar
Thomas Witkowski committed
174
    /// Returns node[i] of the mesh 
175
176
    inline int getNode(int i) const 
    { 
177
      return node[i]; 
178
    }
179
180
181
182
183
184
185

    /** \brief
     * Allocates the number of DOFs needed at position and registers the DOFs
     * at the DOFAdmins. The number of needed DOFs is the sum over the needed
     * DOFs of all DOFAdmin objects belonging to this mesh. 
     * The return value is a pointer to the first allocated DOF. 
     */
186
    DegreeOfFreedom *getDof(GeoIndex position);
187

Thomas Witkowski's avatar
Thomas Witkowski committed
188
    /// Returns *(\ref admin[i]) of the mesh
189
190
    inline const DOFAdmin& getDOFAdmin(int i) const 
    {
191
      return *(admin[i]);
192
    }
193
194
195
196
197
198

    /** \brief
     * Creates a DOFAdmin with name lname. nDOF specifies how many DOFs 
     * are needed at the different positions (see \ref DOFAdmin::nrDOF).
     * A pointer to the created DOFAdmin is returned.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
199
    const DOFAdmin* createDOFAdmin(std::string lname, DimVec<int> nDOF);
200
201
202
203
204

    /** \brief
     * Returns the size of \ref admin which is the number of the DOFAdmins
     * belonging to this mesh
     */
205
206
    const int getNumberOfDOFAdmin() const 
    {
207
      return admin.size();
208
    }
209
210
211
212
213

    /** \brief
     * Returns the size of \ref macroElements which is the number of
     * of macro elements of this mesh
     */
214
215
    const int getNumberOfMacros() const 
    {
216
      return macroElements.size();
217
    }
218

Thomas Witkowski's avatar
Thomas Witkowski committed
219
    /// Returns a DOFAdmin which at least manages vertex DOFs
220
221
    const DOFAdmin* getVertexAdmin() const;

Thomas Witkowski's avatar
Thomas Witkowski committed
222
    /// Allocates a array of DOF pointers. The array holds one pointer for each node.
Thomas Witkowski's avatar
Thomas Witkowski committed
223
    DegreeOfFreedom **createDofPtrs();
224

Thomas Witkowski's avatar
Thomas Witkowski committed
225
    /// Returns \ref preserveCoarseDOFs of the mesh
226
227
    inline bool queryCoarseDOFs() const 
    { 
228
      return preserveCoarseDOFs;
229
    }
230

Thomas Witkowski's avatar
Thomas Witkowski committed
231
    /// Returns an iterator to the begin of \ref macroElements
232
233
    inline std::deque<MacroElement*>::iterator firstMacroElement() 
    {
234
      return macroElements.begin();
235
    }
236

Thomas Witkowski's avatar
Thomas Witkowski committed
237
    /// Returns macroElements[i].
238
239
    inline MacroElement *getMacroElement(int i) 
    { 
240
      return macroElements[i]; 
241
    }
242

243
244
245
246
247
    std::deque<MacroElement*>& getMacroElements()
    {
      return macroElements;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
248
    /// Returns an iterator to the end of \ref macroElements
249
250
    inline std::deque<MacroElement*>::iterator endOfMacroElements() 
    {
251
      return macroElements.end();
252
    }
253
254
255
256
257
258
259

    /** \} */

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

Thomas Witkowski's avatar
Thomas Witkowski committed
260
    /// Sets \ref name of the mesh
Thomas Witkowski's avatar
Thomas Witkowski committed
261
    inline void setName(std::string aName) 
262
    { 
263
      name = aName;
264
    }
265

Thomas Witkowski's avatar
Thomas Witkowski committed
266
    /// Sets \ref nVertices of the mesh
267
268
    inline void setNumberOfVertices(int n) 
    { 
269
      nVertices = n; 
270
    }
271

Thomas Witkowski's avatar
Thomas Witkowski committed
272
    /// Sets \ref nFaces of the mesh
273
274
    inline void setNumberOfFaces(int n) 
    { 
275
      nFaces = n; 
276
    }
277

Thomas Witkowski's avatar
Thomas Witkowski committed
278
    /// Increments \ref nVertices by inc
279
280
    inline void incrementNumberOfVertices(int inc) 
    { 
281
      nVertices += inc; 
282
    }
283
 
Thomas Witkowski's avatar
Thomas Witkowski committed
284
    /// Sets \ref nEdges of the mesh
285
286
    inline void setNumberOfEdges(int n) 
    { 
287
      nEdges = n; 
288
    }
289

Thomas Witkowski's avatar
Thomas Witkowski committed
290
    /// Increments \ref nEdges by inc
291
292
    inline void incrementNumberOfEdges(int inc) 
    { 
293
      nEdges += inc; 
294
    }
295

Thomas Witkowski's avatar
Thomas Witkowski committed
296
    /// Increments \ref nFaces by inc
297
298
    inline void incrementNumberOfFaces(int inc) 
    { 
299
      nFaces += inc; 
300
    }
301

Thomas Witkowski's avatar
Thomas Witkowski committed
302
    /// Sets \ref nLeaves of the mesh
303
304
    inline void setNumberOfLeaves(int n) 
    { 
305
      nLeaves = n; 
306
    }
307

Thomas Witkowski's avatar
Thomas Witkowski committed
308
    /// Increments \ref nLeaves by inc
309
310
    inline void incrementNumberOfLeaves(int inc) 
    { 
311
      nLeaves += inc; 
312
    }
313

Thomas Witkowski's avatar
Thomas Witkowski committed
314
    /// Sets \ref nElements of the mesh
315
316
    inline void setNumberOfElements(int n) 
    { 
317
      nElements = n; 
318
    }
319

Thomas Witkowski's avatar
Thomas Witkowski committed
320
    /// Increments \ref nElements by inc
321
322
    inline void incrementNumberOfElements(int inc) 
    { 
323
      nElements += inc; 
324
    }
325

Thomas Witkowski's avatar
Thomas Witkowski committed
326
    /// Sets *\ref diam to w
327
328
    void setDiameter(const WorldVector<double>& w);

Thomas Witkowski's avatar
Thomas Witkowski committed
329
    /// Sets (*\ref diam)[i] to d
330
331
    void setDiameter(int i, double d);

Thomas Witkowski's avatar
Thomas Witkowski committed
332
    /// Sets \ref preserveCoarseDOFs = true
333
334
    inline void retainCoarseDOFs() 
    {
335
      preserveCoarseDOFs = true;
336
    }
337

Thomas Witkowski's avatar
Thomas Witkowski committed
338
    /// Sets \ref preserveCoarseDOFs = b
339
340
    inline void setPreserveCoarseDOFs(bool b) 
    {
341
      preserveCoarseDOFs = b;
342
    }
343

Thomas Witkowski's avatar
Thomas Witkowski committed
344
    /// Sets \ref preserveCoarseDOFs = false
345
346
    inline void noCoarseDOFs() 
    {
347
      preserveCoarseDOFs = false;
348
    }
349

Thomas Witkowski's avatar
Thomas Witkowski committed
350
    /// Sets \ref elementPrototype of the mesh
351
352
    inline void setElementPrototype(Element* prototype) 
    {
353
      elementPrototype = prototype;
354
355
    }
    
Thomas Witkowski's avatar
Thomas Witkowski committed
356
    /// Sets \ref elementDataPrototype of the mesh
357
358
    inline void setElementDataPrototype(ElementData* prototype) 
    {
359
      elementDataPrototype = prototype;
360
    }
361

Thomas Witkowski's avatar
Thomas Witkowski committed
362
    ///
363
364
    inline void setParametric(Parametric *param) 
    {
365
      parametric = param;
366
    }
367

Thomas Witkowski's avatar
Thomas Witkowski committed
368
    ///
369
370
    inline void setMaxEdgeNeigh(int m) 
    { 
371
      maxEdgeNeigh = m; 
372
    }
373
374
375
  
    /** \} */

Thomas Witkowski's avatar
Thomas Witkowski committed
376
    /// Creates a new Element by cloning \ref elementPrototype
377
378
    Element* createNewElement(Element *parent = NULL);

Thomas Witkowski's avatar
Thomas Witkowski committed
379
    /// Creates a new ElInfo dependent of \ref dim of the mesh
380
381
    ElInfo* createNewElInfo();

Thomas Witkowski's avatar
Thomas Witkowski committed
382
    /// Frees DOFs at the given position pointed by dof 
383
    void freeDof(DegreeOfFreedom* dof, GeoIndex position);
384

Thomas Witkowski's avatar
Thomas Witkowski committed
385
    /// Frees memory for the given element el
386
387
    void freeElement(Element* el);

Thomas Witkowski's avatar
Thomas Witkowski committed
388
    /// Performs DOF compression for all DOFAdmins (see \ref DOFAdmin::compress)
389
390
    void dofCompress();

Thomas Witkowski's avatar
Thomas Witkowski committed
391
    /// Adds a DOFAdmin to the mesh
392
    virtual void addDOFAdmin(DOFAdmin *admin);
393

394
395
396
    /// Recalculates the number of leave elements.
    void updateNumberOfLeaves();

Thomas Witkowski's avatar
Thomas Witkowski committed
397
    /// Clears \ref macroElements
398
399
    inline void clearMacroElements() 
    { 
400
      macroElements.clear();
401
    }
402
  
Thomas Witkowski's avatar
Thomas Witkowski committed
403
    /// Adds a macro element to the mesh
404
405
    void addMacroElement(MacroElement* me);

406
    /* \brief
407
408
409
     * Removes a set of macro elements from the mesh. This works only for the case, 
     * that there are no global or local refinements, i.e., all macro elements have 
     * no children.
410
     */
411
    void removeMacroElements(std::set<MacroElement*>& macros,
Thomas Witkowski's avatar
Thomas Witkowski committed
412
			     const FiniteElemSpace* feSpace);
413

Thomas Witkowski's avatar
Thomas Witkowski committed
414
    /// Frees the array of DOF pointers (see \ref createDofPtrs)
415
416
    void freeDOFPtrs(DegreeOfFreedom **ptrs);

Thomas Witkowski's avatar
Thomas Witkowski committed
417
    /// Used by \ref findElementAtPoint. 
418
419
420
    bool findElInfoAtPoint(const WorldVector<double>& xy,
			   ElInfo *el_info,
			   DimVec<double>& bary,
421
			   const MacroElement *start_mel,
422
423
			   const WorldVector<double> *xy0,
			   double *sp);
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

    /** \brief
     * Access to an element at world coordinates xy. Some applications need the 
     * access to elements at a special location in world coordinates. Examples 
     * are characteristic methods for convection problems, or the implementation
     * of a special right hand side like point evaluations or curve integrals.
     * For such purposes, a routine is available which returns an element pointer
     * and corresponding barycentric coordinates.
     *
     * \param xy world coordinates of point
     * \param elp return address for a pointer to the element at xy
     * \param pary returns barycentric coordinates of xy
     * \param start_mel initial guess for the macro element containing xy or NULL
     * \param xy0 start point from a characteristic method, see below, or NULL
     * \param sp return address for relative distance to domain boundary in a 
     *        characteristic method, see below, or NULL
     * \return true is xy is inside the domain , false otherwise
     * 
     * For a characteristic method, where \f$ xy = xy_0 - V\tau \f$, it may be 
     * convenient to know the point on the domain's boundary which lies on the 
     * line segment between the old point xy0 and the new point xy, in case that 
     * xy is outside the domain. Such information is returned when xy0 and a 
     * pointer sp!=NULL are supplied: *sp is set to the value s such that 
     * \f$ xy_0 +s (xy -xy_0) \in \partial Domain \f$, and the element and local 
     * coordinates corresponding to that boundary point will be returned via elp 
     * and bary.
     *
     * The implementation of findElementAtPoint() is based on the transformation 
     * from world to local coordinates, available via the routine worldToCoord(),
     * At the moment, findElementAtPoint() works correctly only for domains with 
     * non-curved boundary. This is due to the fact that the implementation first
     * looks for the macro-element containing xy and then finds its path through 
     * the corresponding element tree based on the macro barycentric coordinates.
     * For non-convex domains, it is possible that in some cases a point inside
     * the domain is considered as external.
     */
460
461
462
    bool findElementAtPoint(const WorldVector<double>& xy,
			    Element **elp, 
			    DimVec<double>& bary,
463
			    const MacroElement *start_mel,
464
465
			    const WorldVector<double> *xy0,
			    double *sp);
466

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
    /** \brief
     * Returns for a given dof its world coordinates in this mesh. Because we do
     * not have any direct connection between dofs and coordinates, this function
     * has to search for the element in this mesh, that contains the dof. Than the
     * coordinates can be computed. Therefore, this function is very costly and
     * should be used for debugging purpose only.
     *
     * @param[in]    dof       A pointer to the dof we have to search for.
     * @param[in]    feSpace   The fe space to be used for the search.
     * @param[out]   coords    World vector that stores the coordinates of the dof.
     *
     * The function returns true, if the dof was found, otherwise false.
     */
    bool getDofIndexCoords(const DegreeOfFreedom* dof, 
			   const FiniteElemSpace* feSpace,
482
483
484
485
			   WorldVector<double>& coords)
    {
      return getDofIndexCoords(*dof, feSpace, coords);
    }
486

487
488
489
490
491

    /** \brief
     * This function is equal to \ref getDofIndexCoords as defined above, but takes
     * a DOF index instead of a DOF pointer.
     */
492
493
494
    bool getDofIndexCoords(DegreeOfFreedom dof, 
			   const FiniteElemSpace* feSpace,
			   WorldVector<double>& coords);
495

496
497
498
499
500
501
502
503
504
505
506
    /** \brief
     * Traverse the whole mesh and stores to each DOF of the given finite element space
     * the coordinates in a given DOFVector. Works in the same way as the function
     * \ref getDofIndexCoords defined above.
     *
     * @param[in]   feSpace   The fe soace to be used for the search.
     * @param[out]  coords    DOF vector that stores the coordinates to each dof.
     */
    void getDofIndexCoords(const FiniteElemSpace* feSpace,
			   DOFVector<WorldVector<double> >& coords);

Thomas Witkowski's avatar
Thomas Witkowski committed
507
    /// Returns FILL_ANY_?D
508
509
    inline static const Flag& getFillAnyFlag(int dim) 
    {
510
      switch (dim) {
511
512
513
514
515
516
517
518
519
520
521
522
523
      case 1:
	return FILL_ANY_1D;
	break;
      case 2:
	return FILL_ANY_2D;
	break;
      case 3:
	return FILL_ANY_3D;
	break;
      default:
	ERROR_EXIT("invalid dim\n");
	return FILL_ANY_1D;
      }
524
    }
525

Thomas Witkowski's avatar
Thomas Witkowski committed
526
    /// Serialize the mesh to a file.
527
    void serialize(std::ostream &out);
528

Thomas Witkowski's avatar
Thomas Witkowski committed
529
    /// Deserialize a mesh from a file.
530
    void deserialize(std::istream &in);
531

Thomas Witkowski's avatar
Thomas Witkowski committed
532
    /// Returns \ref elementIndex and increments it by 1.
533
534
    inline int getNextElementIndex() 
    { 
535
      return elementIndex++; 
536
    }
537

Thomas Witkowski's avatar
Thomas Witkowski committed
538
    /// Returns \ref initialized.
539
540
    inline bool isInitialized() 
    {
541
542
      return initialized; 
    }
543
  
Thomas Witkowski's avatar
Thomas Witkowski committed
544
    ///
545
546
    inline std::map<BoundaryType, VertexVector*>& getPeriodicAssociations() 
    {
547
      return periodicAssociations;
548
    }
549

550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
    /// Returns the periodic association for a specific boundary type.
    inline VertexVector& getPeriodicAssociations(BoundaryType b)
    {
      FUNCNAME("Mesh::getPeriodicAssociations()");

      TEST_EXIT_DBG(periodicAssociations.count(b) == 1)
	("There are no periodic assoications for boundary type %d!\n", b);

      return (*(periodicAssociations[b]));
    }

    
    /// Returns whether the given boundary type is periodic, i.e., if there is
    /// a periodic association for this boundary type.
    inline bool isPeriodicAssociation(BoundaryType b)
    {
      return (periodicAssociations.count(b) == 1 ? true : false);
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
569
    ///
570
571
    bool associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2);

Thomas Witkowski's avatar
Thomas Witkowski committed
572
    ///
573
574
    bool indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2);

Thomas Witkowski's avatar
Thomas Witkowski committed
575
    /// Returns \macroFileInfo
576
577
    inline MacroInfo* getMacroFileInfo() 
    { 
578
      return macroFileInfo;
579
    }
580

581
582
583
584
585
586
587
588
589
590
591
592
    /// Increment the value of mesh change index, see \ref changeIndex.
    inline void incChangeIndex()
    {
      changeIndex++;
    }

    /// Returns the mesh change index, see \ref changeIndex.
    inline long getChangeIndex()
    {
      return changeIndex;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
593
    ///
594
595
    void clearMacroFileInfo();

596
597
598
599
600
601
602
    /** \brief
     * Traverse this mesh to compute the number of non zero elements the assembled 
     * matrix will have in each row.
     */
    void computeMatrixFillin(const FiniteElemSpace *feSpace,
			     std::vector<int> &nnzInRow, int &overall, int &average);

Thomas Witkowski's avatar
Thomas Witkowski committed
603
    ///
604
605
    int calcMemoryUsage();

606
607
608
    ///
    void deleteMeshStructure();

609
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
610
    ///
611
612
    static const Flag FILL_NOTHING;

Thomas Witkowski's avatar
Thomas Witkowski committed
613
    ///
614
    static const Flag FILL_COORDS; 
615

Thomas Witkowski's avatar
Thomas Witkowski committed
616
    ///
617
    static const Flag FILL_BOUND; 
618

Thomas Witkowski's avatar
Thomas Witkowski committed
619
    ///
620
    static const Flag FILL_NEIGH; 
621

Thomas Witkowski's avatar
Thomas Witkowski committed
622
    ///
623
    static const Flag FILL_OPP_COORDS; 
624

Thomas Witkowski's avatar
Thomas Witkowski committed
625
    ///
626
627
    static const Flag FILL_ORIENTATION; 

Thomas Witkowski's avatar
Thomas Witkowski committed
628
    ///
629
    static const Flag FILL_ADD_ALL; 
630
  
Thomas Witkowski's avatar
Thomas Witkowski committed
631
    ///
632
    static const Flag FILL_ANY_1D; 
633

Thomas Witkowski's avatar
Thomas Witkowski committed
634
    ///
635
    static const Flag FILL_ANY_2D; 
636

Thomas Witkowski's avatar
Thomas Witkowski committed
637
    ///
638
    static const Flag FILL_ANY_3D; 
639

Thomas Witkowski's avatar
Thomas Witkowski committed
640
    ///
641
    static const Flag FILL_DET;
642

Thomas Witkowski's avatar
Thomas Witkowski committed
643
    ///
644
645
646
647
648
649
    static const Flag FILL_GRD_LAMBDA;

    //**************************************************************************
    //  flags for Mesh traversal                                                
    //**************************************************************************

Thomas Witkowski's avatar
Thomas Witkowski committed
650
    ///
651
652
    static const Flag CALL_EVERY_EL_PREORDER;      

Thomas Witkowski's avatar
Thomas Witkowski committed
653
    ///
654
655
    static const Flag CALL_EVERY_EL_INORDER;     

Thomas Witkowski's avatar
Thomas Witkowski committed
656
    ///
657
658
    static const Flag CALL_EVERY_EL_POSTORDER;    

Thomas Witkowski's avatar
Thomas Witkowski committed
659
    ///
660
661
    static const Flag CALL_LEAF_EL;   

Thomas Witkowski's avatar
Thomas Witkowski committed
662
    ///
663
664
    static const Flag CALL_LEAF_EL_LEVEL;  

Thomas Witkowski's avatar
Thomas Witkowski committed
665
    ///
666
667
    static const Flag CALL_EL_LEVEL; 

Thomas Witkowski's avatar
Thomas Witkowski committed
668
    ///
669
670
    static const Flag CALL_MG_LEVEL;

671
672
673
    /// If set, left and right children are swapped in traverse.
    static const Flag CALL_REVERSE_MODE;

674
  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
675
    ///
676
    bool findElementAtPointRecursive(ElInfo *elinfo,
677
				     const DimVec<double>& lambda,
678
				     int outside,
679
680
				     ElInfo *final_el_info);

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
    /** \brief
     * This functions is called in parallel computations by the function \ref
     * Mesh::initialize(). It checks that the macro file has enough macro elements
     * for the number of used processors and that all macro elements are of type 0.
     * If this is not the case, that macro mesh is globally refined in an
     * apropriate way and is written to a new macro file.
     *
     * The function returns true, if a new macro and parallel file were created for
     * the current parallel usage. In this case, a new macro file with the same name
     * plus ".tmp", and if required, a new periodic file with the same name plus
     * ".tmp" are created.
     *
     * \param[in]  macroFilename      Name of the macro mesh file.
     * \param[in]  periodicFilename   If periodic boundaries are used, name of the
     *                                periodicity file. Otherwise, the string must
     *                                be empty.
     * \param[in]  check              If the mesh should be checked to be a correct
     *                                AMDiS macro mesh, the value must be 1 and 0
     *                                otherwise.
     */
    bool checkParallelMacroFile(std::string macroFilename, 
				std::string periodicFilename,
				int check);
#endif

707
  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
708
    /// maximal number of DOFs at one position
709
710
    static const int MAX_DOF;

Thomas Witkowski's avatar
Thomas Witkowski committed
711
    /// Name of this Mesh
712
    std::string name;
713

Thomas Witkowski's avatar
Thomas Witkowski committed
714
    /// Dimension of this Mesh. Doesn't have to be equal to dimension of world.
715
716
    int dim;

Thomas Witkowski's avatar
Thomas Witkowski committed
717
    /// Number of vertices in this Mesh
718
719
    int nVertices;

Thomas Witkowski's avatar
Thomas Witkowski committed
720
    /// Number of Edges in this Mesh
721
722
    int nEdges;

Thomas Witkowski's avatar
Thomas Witkowski committed
723
    /// Number of leaf elements in this Mesh
724
725
    int nLeaves;

Thomas Witkowski's avatar
Thomas Witkowski committed
726
    /// Total number of elements in this Mesh
727
728
    int nElements;

Thomas Witkowski's avatar
Thomas Witkowski committed
729
    /// Number of faces in this Mesh
730
731
732
733
734
735
736
737
738
    int nFaces;

    /** \brief
     * Maximal number of elements that share one edge; used to allocate memory 
     * to store pointers to the neighbour at the refinement/coarsening edge 
     * (only 3d);
     */
    int maxEdgeNeigh;

Thomas Witkowski's avatar
Thomas Witkowski committed
739
    /// Diameter of the mesh in the DIM_OF_WORLD directions
740
741
742
743
744
745
746
747
748
749
    WorldVector<double> diam;

    /** \brief
     * Is pointer to NULL if mesh contains no parametric elements else pointer 
     * to a Parametric object containing coefficients of the parameterization 
     * and related information
     */
    Parametric *parametric;

    /** \brief
750
751
752
753
754
755
756
     * When an element is refined, not all dofs of the coarse element must be 
     * part of the new elements. An example are centered dofs when using higher
     * lagrange basis functions. The midpoint dof of the parents element is not
     * a dof of the both children elements. Therefore, the dof can be deleted. In
     * some situation, e.g., when using multigrid techniques, it can be necessary to
     * store this coarse dofs. Then this variable must be set to true. If false, the
     * not required coarse dofs will be deleted.
757
758
759
     */
    bool preserveCoarseDOFs;

Thomas Witkowski's avatar
Thomas Witkowski committed
760
    /// Number of all DOFs on a single element
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
    int nDOFEl;

    /** \brief
     * Number of DOFs at the different positions VERTEX, EDGE, (FACE,) CENTER on
     * an element:
     *
     * - nDOF[VERTEX]: number of DOFs at a vertex (>= 1)
     *
     * - nDOF[EDGE]: number of DOFs at an edge; if no DOFs are associated to
     *   edges, then this value is 0
     *
     * - nDOF[FACE]: number of DOFs at a face; if no DOFs are associated to
     *   faces, then this value is 0 (only 3d)
     *
     * - nDOF[CENTER]: number of DOFs at the barycenter; if no DOFs are 
     *   associated to the barycenter, then this value is 0
     */
    DimVec<int> nDOF;

    /** \brief
     * Number of nodes on a single element where DOFs are located; needed for 
     * the (de-) allocation of the dof-vector on the element (\ref Element::dof);
     */
    int nNodeEl;

    /** \brief
     * Gives the index of the first node at vertex, edge, face (only 3d), and 
     * barycenter:
     *
     * - node[VERTEX]: has always value 0; dof[0],...,dof[N_VERTICES-1] are 
     *   always DOFs at the vertices;
     *
     * - node[EDGE]: dof[node[EDGE]],..., dof[node[EDGE]+N_EDGES-1] are the DOFs
     *   at the N_EDGES edges, if DOFs are located at edges;
     *
     * - node[FACE]: dof[node[FACE]],..., dof[node[FACE]+N_FACES-1] are the DOFs
     *   at the N_FACES faces, if DOFs are located at faces (only 3d);
     *
     * - node[CENTER]: dof[node[CENTER]] are the DOFs at the barycenter, if DOFs
     *   are located at the barycenter;
     */
    DimVec<int> node;

Thomas Witkowski's avatar
Thomas Witkowski committed
804
    /// List of all DOFAdmins
805
    std::vector<DOFAdmin*> admin;
806

Thomas Witkowski's avatar
Thomas Witkowski committed
807
    /// List of all MacroElements of this Mesh
808
    std::deque<MacroElement*> macroElements;
809

Thomas Witkowski's avatar
Thomas Witkowski committed
810
    /// Needed during DOF compression (\ref DOFAdmin::compress).
811
    std::vector<DegreeOfFreedom> newDOF;
812

Thomas Witkowski's avatar
Thomas Witkowski committed
813
    /// Used by check functions
814
    static std::vector<DegreeOfFreedom> dof_used;
815

816
817
818
819
820
821
822
823
824
825
826
    /** \brief
     * This map is used for serialization and deserialization of mesh elements. 
     * During the serialization process, all elements are visited and their dof indices
     * are written to the file. If a dof index at a position, i.e. vertex, line or face,
     * was written to file, the combination of dof index and position is inserted to
     * this map. That ensures that the same dof at the same position, but being part of
     * another element, is not written twice to the file. 
     * When a state should be deserialized, the information can be used to construct
     * exactly the same dof structure.
     */
    static std::map<std::pair<DegreeOfFreedom, int>, DegreeOfFreedom*> serializedDOFs;
827
828
829
830
831
832
833
834
835

    /** \brief
     * Used while mesh refinement. To create new elements 
     * elementPrototype->clone() is called, which returns a Element of the
     * same type as elementPrototype. So e.g. Elements of the different
     * dimensions can be created in a uniform way. 
     */
    Element* elementPrototype;

Thomas Witkowski's avatar
Thomas Witkowski committed
836
    /// Prototype for leaf data. Used for creation of new leaf data while refinement.
837
838
    ElementData* elementDataPrototype;

Thomas Witkowski's avatar
Thomas Witkowski committed
839
    /// Used for enumeration of all mesh elements
840
841
    int elementIndex;

Thomas Witkowski's avatar
Thomas Witkowski committed
842
    /// True if the mesh is already initialized, false otherwise.
843
844
    bool initialized;

Thomas Witkowski's avatar
Thomas Witkowski committed
845
    /// Map of managed periodic vertex associations.
846
    std::map<BoundaryType, VertexVector*> periodicAssociations;
847
848

    /** \brief
849
850
     * If the mesh has been created by reading a macro file, here the information are
     * are stored about the content of the file.
851
     */
852
    MacroInfo *macroFileInfo;
853

854
855
856
857
858
859
860
    /** \brief
     * This index is incremented every time the mesh is changed, e.g. by the refinement
     * or the coarsening manager. It can be used by other object if the mesh has been
     * changed by first copying this variable elsewhere and comparing its values.
     */
    long changeIndex;

861
  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
862
    /// for findElement-Fcts
863
    DimVec<double> final_lambda;
864
865

    /** \brief
866
867
     * Temporary variables that are used in functions \ref fineElInfoatPoint and
     * \ref fineElementAtPointRecursive.
868
     */
869
    const WorldVector<double> *g_xy0, *g_xy;
870
871

    /** \brief
872
873
     * Temporary variable that is used in functions \ref fineElInfoatPoint and
     * \ref fineElementAtPointRecursive.
874
875
     */    
    double *g_sp;
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
   
    friend class MacroInfo;
    friend class MacroReader;
    friend class MacroWriter;
    friend class MacroElement;
    friend class Element;
    friend void Element::newDOFFct1(const DOFAdmin*);
    friend void Element::newDOFFct2(const DOFAdmin*);
  };

}

#endif  // AMDIS_MESH_H