Mesh.h 25.5 KB
Newer Older
1
2
3
4
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
5
// ==  http://www.amdis-fem.org                                              ==
6
7
// ==                                                                        ==
// ============================================================================
8
9
10
11
12
13
14
15
16
17
18
19
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

/** \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
37
38
39
40
#include <deque>
#include <set>
#include <stdio.h>
#include "AMDiS_fwd.h"
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#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
60
    /// Creates a mesh with the given name of dimension dim
Thomas Witkowski's avatar
Thomas Witkowski committed
61
    Mesh(std::string name, int dim);
62

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
69
    /// Assignment operator
70
71
72
73
74
75
76
77
    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
78
     * specified which information is requested.
79
     */
80
81
    inline int getGeo(GeoIndex p) const 
    { 
82
      return Global::getGeo(p, dim); 
83
    }
84

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

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

97
98
    /// Returns \ref nDofEl of the mesh
    inline const int getNumberOfAllDofs() const 
99
    { 
100
      return nDofEl; 
101
    }
102

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

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

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

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

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

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

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

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

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

157
158
    /// Returns nDof[i] of the mesh
    inline const int getNumberOfDofs(int i) const 
159
    { 
160
      return nDof[i]; 
161
    }
162

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

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

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

    /** \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. 
     */
187
    DegreeOfFreedom *getDof(GeoIndex position);
188

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

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

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

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

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

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

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

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
244
    /// Returns an iterator to the end of \ref macroElements
245
246
    inline std::deque<MacroElement*>::iterator endOfMacroElements() 
    {
247
      return macroElements.end();
248
    }
249

250
251
252
253
254
255
    /// Returns \ref macroElements, the list of all macro elements in the mesh.
    std::deque<MacroElement*>& getMacroElements()
    {
      return macroElements;
    }

256
257
258
259
260
261
    /** \} */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

396
397
398
    /// Recalculates the number of leave elements.
    void updateNumberOfLeaves();

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

408
    /* \brief
409
410
411
     * 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.
412
     */
413
    void removeMacroElements(std::set<MacroElement*>& macros,
Thomas Witkowski's avatar
Thomas Witkowski committed
414
			     const FiniteElemSpace* feSpace);
415

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

Thomas Witkowski's avatar
Thomas Witkowski committed
419
    /// Used by \ref findElementAtPoint. 
420
421
422
    bool findElInfoAtPoint(const WorldVector<double>& xy,
			   ElInfo *el_info,
			   DimVec<double>& bary,
423
			   const MacroElement *start_mel,
424
425
			   const WorldVector<double> *xy0,
			   double *sp);
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
460
461

    /** \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.
     */
462
463
464
    bool findElementAtPoint(const WorldVector<double>& xy,
			    Element **elp, 
			    DimVec<double>& bary,
465
			    const MacroElement *start_mel,
466
467
			    const WorldVector<double> *xy0,
			    double *sp);
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
    /** \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,
484
485
486
487
			   WorldVector<double>& coords)
    {
      return getDofIndexCoords(*dof, feSpace, coords);
    }
488

489
490
491
492
493

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

498
499
500
501
502
503
504
505
506
507
508
    /** \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
509
    /// Returns FILL_ANY_?D
510
511
    inline static const Flag& getFillAnyFlag(int dim) 
    {
512
      switch (dim) {
513
514
515
516
517
518
519
520
521
522
523
524
525
      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;
      }
526
    }
527

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

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

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

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

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
    /// 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
571
    ///
572
573
    bool associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2);

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

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

583
584
585
586
587
588
589
590
591
592
593
594
    /// 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
595
    ///
596
597
    void clearMacroFileInfo();

Thomas Witkowski's avatar
Thomas Witkowski committed
598
    ///
599
600
    int calcMemoryUsage();

601
602
603
    ///
    void deleteMeshStructure();

604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
    /// In parallel computations the level of all macro elements is equal to the number
    /// of global pre refinements, \ref nParallelPreRefinements.
    inline int getMacroElementLevel()
    {
      return nParallelPreRefinements;
    }
#else
    /// In sequentiel computations the level of all macro elements is always 0.
    inline int getMacroElementLevel()
    {
      return 0;
    }
#endif

619
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
620
    ///
621
622
    static const Flag FILL_NOTHING;

Thomas Witkowski's avatar
Thomas Witkowski committed
623
    ///
624
    static const Flag FILL_COORDS; 
625

Thomas Witkowski's avatar
Thomas Witkowski committed
626
    ///
627
    static const Flag FILL_BOUND; 
628

Thomas Witkowski's avatar
Thomas Witkowski committed
629
    ///
630
    static const Flag FILL_NEIGH; 
631

Thomas Witkowski's avatar
Thomas Witkowski committed
632
    ///
633
    static const Flag FILL_OPP_COORDS; 
634

Thomas Witkowski's avatar
Thomas Witkowski committed
635
    ///
636
637
    static const Flag FILL_ORIENTATION; 

Thomas Witkowski's avatar
Thomas Witkowski committed
638
    ///
639
    static const Flag FILL_ADD_ALL; 
640
  
Thomas Witkowski's avatar
Thomas Witkowski committed
641
    ///
642
    static const Flag FILL_ANY_1D; 
643

Thomas Witkowski's avatar
Thomas Witkowski committed
644
    ///
645
    static const Flag FILL_ANY_2D; 
646

Thomas Witkowski's avatar
Thomas Witkowski committed
647
    ///
648
    static const Flag FILL_ANY_3D; 
649

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

Thomas Witkowski's avatar
Thomas Witkowski committed
653
    ///
654
655
656
657
658
659
    static const Flag FILL_GRD_LAMBDA;

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

Thomas Witkowski's avatar
Thomas Witkowski committed
660
    ///
661
    static const Flag CALL_EVERY_EL_PREORDER;
662

Thomas Witkowski's avatar
Thomas Witkowski committed
663
    ///
664
    static const Flag CALL_EVERY_EL_INORDER;
665

Thomas Witkowski's avatar
Thomas Witkowski committed
666
    ///
667
    static const Flag CALL_EVERY_EL_POSTORDER;
668

Thomas Witkowski's avatar
Thomas Witkowski committed
669
    ///
670
    static const Flag CALL_LEAF_EL;
671

Thomas Witkowski's avatar
Thomas Witkowski committed
672
    ///
673
    static const Flag CALL_LEAF_EL_LEVEL;
674

Thomas Witkowski's avatar
Thomas Witkowski committed
675
    ///
676
    static const Flag CALL_EL_LEVEL;
677

Thomas Witkowski's avatar
Thomas Witkowski committed
678
    ///
679
680
    static const Flag CALL_MG_LEVEL;

681
682
683
    /// If set, left and right children are swapped in traverse.
    static const Flag CALL_REVERSE_MODE;

684
  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
685
    ///
686
    bool findElementAtPointRecursive(ElInfo *elinfo,
687
				     const DimVec<double>& lambda,
688
				     int outside,
689
690
				     ElInfo *final_el_info);

691
692
693
694
695
696
697
698
#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.
     *
699
700
     * The function overwrittes the macro and periodic filenames, if a new macro
     * fule was created for the current parallel usage.
701
     *
702
703
704
705
706
707
708
     * \param[in/out]  macroFilename      Name of the macro mesh file.
     * \param[in/out]  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.
709
     */
710
711
    void checkParallelMacroFile(std::string &macroFilename, 
				std::string &periodicFilename,
712
713
714
				int check);
#endif

715
  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
716
    /// maximal number of DOFs at one position
717
718
    static const int MAX_DOF;

Thomas Witkowski's avatar
Thomas Witkowski committed
719
    /// Name of this Mesh
720
    std::string name;
721

Thomas Witkowski's avatar
Thomas Witkowski committed
722
    /// Dimension of this Mesh. Doesn't have to be equal to dimension of world.
723
724
    int dim;

Thomas Witkowski's avatar
Thomas Witkowski committed
725
    /// Number of vertices in this Mesh
726
727
    int nVertices;

Thomas Witkowski's avatar
Thomas Witkowski committed
728
    /// Number of Edges in this Mesh
729
730
    int nEdges;

Thomas Witkowski's avatar
Thomas Witkowski committed
731
    /// Number of leaf elements in this Mesh
732
733
    int nLeaves;

Thomas Witkowski's avatar
Thomas Witkowski committed
734
    /// Total number of elements in this Mesh
735
736
    int nElements;

Thomas Witkowski's avatar
Thomas Witkowski committed
737
    /// Number of faces in this Mesh
738
739
740
741
742
743
744
745
746
    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
747
    /// Diameter of the mesh in the DIM_OF_WORLD directions
748
749
750
751
752
753
754
755
756
757
    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
758
759
760
761
762
763
764
     * 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.
765
766
767
     */
    bool preserveCoarseDOFs;

Thomas Witkowski's avatar
Thomas Witkowski committed
768
    /// Number of all DOFs on a single element
769
    int nDofEl;
770
771
772
773
774

    /** \brief
     * Number of DOFs at the different positions VERTEX, EDGE, (FACE,) CENTER on
     * an element:
     *
775
     * - nDof[VERTEX]: number of DOFs at a vertex (>= 1)
776
     *
777
     * - nDof[EDGE]: number of DOFs at an edge; if no DOFs are associated to
778
779
     *   edges, then this value is 0
     *
780
     * - nDof[FACE]: number of DOFs at a face; if no DOFs are associated to
781
782
     *   faces, then this value is 0 (only 3d)
     *
783
     * - nDof[CENTER]: number of DOFs at the barycenter; if no DOFs are 
784
785
     *   associated to the barycenter, then this value is 0
     */
786
    DimVec<int> nDof;
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811

    /** \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
812
    /// List of all DOFAdmins
813
    std::vector<DOFAdmin*> admin;
814

Thomas Witkowski's avatar
Thomas Witkowski committed
815
    /// List of all MacroElements of this Mesh
816
    std::deque<MacroElement*> macroElements;
817

Thomas Witkowski's avatar
Thomas Witkowski committed
818
    /// Used by check functions
819
    static std::vector<DegreeOfFreedom> dof_used;
820

821
822
823
824
825
826
827
828
829
830
831
    /** \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;
832
833
834
835
836
837
838
839
840

    /** \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
841
    /// Prototype for leaf data. Used for creation of new leaf data while refinement.
842
843
    ElementData* elementDataPrototype;

Thomas Witkowski's avatar
Thomas Witkowski committed
844
    /// Used for enumeration of all mesh elements
845
846
    int elementIndex;

Thomas Witkowski's avatar
Thomas Witkowski committed
847
    /// True if the mesh is already initialized, false otherwise.
848
849
    bool initialized;

Thomas Witkowski's avatar
Thomas Witkowski committed
850
    /// Map of managed periodic vertex associations.
851
    std::map<BoundaryType, VertexVector*> periodicAssociations;
852
853

    /** \brief
854
855
     * If the mesh has been created by reading a macro file, here the information are
     * are stored about the content of the file.
856
     */
857
    MacroInfo *macroFileInfo;
858

859
860
861
862
863
864
865
    /** \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;

866
867
868
869
870
871
872
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
    /// In parallel computations the mesh may be globally prerefined to achieve a fine
    /// enought starting mesh for the given number of ranks. The value of the variable
    /// will be defined in function \ref checkParallelMacroFile.
    int nParallelPreRefinements;
#endif

873
  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
874
    /// for findElement-Fcts
875
    DimVec<double> final_lambda;
876
877

    /** \brief
878
879
     * Temporary variables that are used in functions \ref fineElInfoatPoint and
     * \ref fineElementAtPointRecursive.
880
     */
881
    const WorldVector<double> *g_xy0, *g_xy;
882
883

    /** \brief
884
885
     * Temporary variable that is used in functions \ref fineElInfoatPoint and
     * \ref fineElementAtPointRecursive.
886
887
     */    
    double *g_sp;
888
889
890
891
892
893
894
895
896
897
898
899
900
   
    friend class MacroInfo;
    friend class MacroReader;
    friend class MacroWriter;
    friend class MacroElement;
    friend class Element;
  };

}

#endif  // AMDIS_MESH_H