ElementObjectDatabase.h 17.3 KB
Newer Older
Thomas Witkowski's avatar
Thomas Witkowski committed
1
2
3
4
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
5
// ==  http://www.amdis-fem.org                                              ==
Thomas Witkowski's avatar
Thomas Witkowski committed
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.


Thomas Witkowski's avatar
Thomas Witkowski committed
20

21
/** \file ElementObjectDatabase.h */
Thomas Witkowski's avatar
Thomas Witkowski committed
22

23
24
#ifndef AMDIS_ELEMENT_OBJECT_DATABASE_H
#define AMDIS_ELEMENT_OBJECT_DATABASE_H
Thomas Witkowski's avatar
Thomas Witkowski committed
25
26
27
28
29
30

#include <map>
#include <vector>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>

31
#include "AMDiS_fwd.h"
32
#include "Containers.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
33
34
#include "Global.h"
#include "Boundary.h"
35
#include "Serializer.h"
36
#include "FiniteElemSpace.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
37
38
39

namespace AMDiS {

40
41
  using namespace std;

42
  /// Just to templatize the typedef.
43
  template<typename T>
44
  struct PerBoundMap {
45
46
47
48
    typedef map<pair<T, T>, BoundaryType> type;
    typedef typename type::iterator iterator;
  };

49
50

  /// Defines one element object. This may be either a vertex, edge or face.
Thomas Witkowski's avatar
Thomas Witkowski committed
51
  struct ElementObjectData {
52
    ElementObjectData(int a = -1, int b = 0)
Thomas Witkowski's avatar
Thomas Witkowski committed
53
      : elIndex(a),
Thomas Witkowski's avatar
Thomas Witkowski committed
54
55
	ithObject(b),
	mappedOnPeriodicBoundary(false)
Thomas Witkowski's avatar
Thomas Witkowski committed
56
    {}
57
58

    /// Index of the element this object is part of.
Thomas Witkowski's avatar
Thomas Witkowski committed
59
60
    int elIndex;
    
61
    /// Index of the object within the element.
Thomas Witkowski's avatar
Thomas Witkowski committed
62
    int ithObject;
Thomas Witkowski's avatar
Thomas Witkowski committed
63
64
65
66

    /// If true, the element does not exists in mesh but is due to a mapping
    /// on a periodic boundary.
    bool mappedOnPeriodicBoundary;
Thomas Witkowski's avatar
Thomas Witkowski committed
67
    
68
    /// Write this element object to disk.
69
    void serialize(ostream &out) const
70
71
72
    {
      SerUtil::serialize(out, elIndex);
      SerUtil::serialize(out, ithObject);
Thomas Witkowski's avatar
Thomas Witkowski committed
73
      SerUtil::serialize(out, mappedOnPeriodicBoundary);
74
75
    }

76
    /// Read this element object from disk.
77
    void deserialize(istream &in)
78
79
80
    {
      SerUtil::deserialize(in, elIndex);
      SerUtil::deserialize(in, ithObject);
Thomas Witkowski's avatar
Thomas Witkowski committed
81
      SerUtil::deserialize(in, mappedOnPeriodicBoundary);
82
83
    }

84
    /// Compare this element object with another one.
85
86
    bool operator==(ElementObjectData& cmp) const
    {
87
      return (elIndex == cmp.elIndex && ithObject == cmp.ithObject);
88
89
    }

90
    /// Define a strict order on element objects.
91
92
    bool operator<(const ElementObjectData& rhs) const
    {
93
94
      return (elIndex < rhs.elIndex || 
	      (elIndex == rhs.elIndex && ithObject < rhs.ithObject));
95
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
96
97
98
99
  };



100
101
  /** \brief
   * This class is a database of element objects. An element object is either a
102
103
104
105
106
107
108
   * vertex, edge or the face of a specific element. This database is used to
   * store all objects of all elements of a mesh. The information is stored in a
   * way that makes it possible to identify all elements, which have a given
   * vertex, edge or face in common. If is is known which element is owned by 
   * which rank in parallel computations, it is thus possible to get all interior
   * boundaries on object level. This is required, because two elements may share
   * a common vertex without beging neighbours in the definition of AMDiS.
109
   */
110
  class ElementObjectDatabase {
Thomas Witkowski's avatar
Thomas Witkowski committed
111
  public:
112
    ElementObjectDatabase()
113
114
      : feSpace(NULL),
	mesh(NULL),
115
116
	iterGeoPos(CENTER),
	macroElementRankMap(NULL),
117
118
119
120
121
	levelData(NULL),
	removePeriodicBoundary(false)
    {
      Parameters::get("parallel->remove periodic boundary", removePeriodicBoundary);
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
122

123
    void setFeSpace(const FiniteElemSpace *fe)
Thomas Witkowski's avatar
Thomas Witkowski committed
124
    {
125
126
127
128
129
130
131
      feSpace = fe;
      mesh = feSpace->getMesh();
    }
  
    Mesh* getMesh()
    {
      return mesh;
132
133
    }

134
135
136
137
138
139
    /*
     * \param[in]  macroElementRankMap   Maps to each macro element of the mesh
     *                                   the rank that owns this macro element.
     */
    void create(map<int, int>& macroElementRankMap,
		MeshLevelData& levelData);
140

141
    void createMacroElementInfo(vector<MacroElement*> &mel);
142
143

    /** \brief
144
145
146
     * Create for a filled object database the membership information for all
     * element objects. An object is owned by a rank, if the rank has the
     * heighest rank number of all ranks where the object is part of.
147
     */
148
    void updateRankData();
149

150
    /** \brief
151
152
153
     * Iterates over all elements for one geometrical index, i.e., over all
     * vertices, edges or faces in the mesh. The function returns true, if the
     * result is valid. Otherwise the iterator is at the end position.
154
     *
155
156
     * \param[in]  pos   Must be either VERTEX, EDGE or FACE and defines the
     *                   elements that should be traversed.
157
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
158
159
    bool iterate(GeoIndex pos)
    {
160
161
162
      // CENTER marks the variable "iterGeoPos" to be in an undefined state. I.e.,
      // there is no iteration that is actually running.

Thomas Witkowski's avatar
Thomas Witkowski committed
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
      if (iterGeoPos == CENTER) {
	iterGeoPos = pos;
	switch (iterGeoPos) {
	case VERTEX:
	  vertexIter = vertexInRank.begin();
	  break;
	case EDGE:
	  edgeIter = edgeInRank.begin();
	  break;
	case FACE:
	  faceIter = faceInRank.begin();
	  break;
	default:
	  ERROR_EXIT("Not GeoIndex %d!\n", iterGeoPos);
	}
      } else {
	switch (iterGeoPos) {
	case VERTEX:
	  ++vertexIter;
	  break;
	case EDGE:
	  ++edgeIter;
	  break;
	case FACE:
	  ++faceIter;
	  break;
	default:
	  ERROR_EXIT("Not GeoIndex %d!\n", iterGeoPos);
	}
      }

      switch (iterGeoPos) {
      case VERTEX:
	if (vertexIter == vertexInRank.end()) {
	  iterGeoPos = CENTER;
	  return false;
	}
	break;
      case EDGE:
	if (edgeIter == edgeInRank.end()) {
	  iterGeoPos = CENTER;
	  return false;
	}
	break;
      case FACE:
	if (faceIter == faceInRank.end()) {
	  iterGeoPos = CENTER;
	  return false;
	}
	break;
      default:
	ERROR_EXIT("Should not happen!\n");	
      }

      return true;
    }


221
    /// Returns the data of the current iterator position.
222
    map<int, ElementObjectData>& getIterateData()
Thomas Witkowski's avatar
Thomas Witkowski committed
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
    {
      switch (iterGeoPos) {
      case VERTEX:
	return vertexIter->second;
	break;
      case EDGE:
	return edgeIter->second;
	break;
      case FACE:
	return faceIter->second;
	break;
      default:
	ERROR_EXIT("Should not happen!\n");

	// Will never be reached, just to avoid compiler warnings.
	return faceIter->second;
      }
    }

242
    /// Returns the rank owner of the current iterator position.
243
    int getIterateOwner(int level);
Thomas Witkowski's avatar
Thomas Witkowski committed
244

245
    /// Returns the rank owner of the current iterator position.
246
    int getIterateMaxLevel();
247

248
    /// Checks if a given vertex DOF is in a given rank.
249
250
251
252
253
    int isInRank(DegreeOfFreedom vertex, int rank)
    {
      return (vertexInRank[vertex].count(rank));
    }

254
    /// Checks if a given edge is in a given rank.
255
256
257
258
259
    int isInRank(DofEdge edge, int rank)
    {
      return (edgeInRank[edge].count(rank));
    }

260
    /// Checks if a given face is in a given rank.
261
262
263
264
265
266
    int isInRank(DofFace face, int rank)
    {
      return (faceInRank[face].count(rank));
    }


267
268
    /// Returns a vector with all macro elements that have a given vertex DOF 
    /// in common.
269
    vector<ElementObjectData>& getElements(DegreeOfFreedom vertex)
Thomas Witkowski's avatar
Thomas Witkowski committed
270
271
272
273
    {
      return vertexElements[vertex];
    }

274
    /// Returns a vector with all macro elements that have a given edge in common.
275
    vector<ElementObjectData>& getElements(DofEdge edge)
Thomas Witkowski's avatar
Thomas Witkowski committed
276
277
278
279
    {
      return edgeElements[edge];
    }

280
    /// Returns a vector with all macro elements that have a given face in common.
281
    vector<ElementObjectData>& getElements(DofFace face)
Thomas Witkowski's avatar
Thomas Witkowski committed
282
283
284
285
    {
      return faceElements[face];
    }

286

287
288
    /// Returns a vector with all macro elements that have a given vertex DOF 
    /// in common.
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    vector<ElementObjectData>& getElementsVertex(int elIndex, int ithVertex)
    {
      ElementObjectData elObj(elIndex, ithVertex);
      DegreeOfFreedom vertex = vertexLocalMap[elObj];
      return vertexElements[vertex];
    }
    
    /// Returns a vector with all macro elements that have a given edge in common.
    vector<ElementObjectData>& getElementsEdge(int elIndex, int ithEdge)
    {
      ElementObjectData elObj(elIndex, ithEdge);
      DofEdge edge = edgeLocalMap[elObj];
      return edgeElements[edge];
    }

    /// Returns a vector with all macro elements that have a given face in common.
    vector<ElementObjectData>& getElementsFace(int elIndex, int ithFace)
    {
      ElementObjectData elObj(elIndex, ithFace);
      DofFace face = faceLocalMap[elObj];
      return faceElements[face];
    }


313
314
315
    
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given vertex DOF in common.
316
    map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex)
317
318
319
320
    {
      return vertexInRank[vertex];
    }

321
322
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given edge in common.
323
    map<int, ElementObjectData>& getElementsInRank(DofEdge edge)
324
325
326
327
    {
      return edgeInRank[edge];
    }

328
329
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given face in common.
330
    map<int, ElementObjectData>& getElementsInRank(DofFace face)
331
332
333
334
    {
      return faceInRank[face];
    }

335
    /// Returns to an element object data the appropriate vertex DOF.
336
337
    DegreeOfFreedom getVertexLocalMap(ElementObjectData &data)
    {
338
339
      TEST_EXIT_DBG(vertexLocalMap.count(data))("Should not happen!\n");

340
341
342
      return vertexLocalMap[data];
    }

343
    /// Returns to an element object data the appropriate edge.
344
345
    DofEdge getEdgeLocalMap(ElementObjectData &data)
    {
346
347
      TEST_EXIT_DBG(edgeLocalMap.count(data))("Should not happen!\n");

348
349
350
      return edgeLocalMap[data];
    }

351
    /// Returns to an element object data the appropriate face.
352
353
    DofFace getFaceLocalMap(ElementObjectData &data)
    {
354
355
      TEST_EXIT_DBG(faceLocalMap.count(data))("Should not happen!\n");

356
357
358
      return faceLocalMap[data];
    }

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    PerBoundMap<DegreeOfFreedom>::type& getPeriodicVertices()
    {
      return periodicVertices;
    }

    PerBoundMap<DofEdge>::type& getPeriodicEdges()
    {
      return periodicEdges;
    }

    PerBoundMap<DofFace>::type& getPeriodicFaces()
    {
      return periodicFaces;
    }

374
375
    inline bool getEdgeReverseMode(ElementObjectData &obj0, 
				   ElementObjectData &obj1)
376
    {
377
378
379
      if (mesh->getDim() == 2)
	return true;

380
381
382
383
384
385
      TEST_EXIT_DBG(edgeReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

      return edgeReverseMode[make_pair(obj0, obj1)];
    }

386
387
    inline bool getFaceReverseMode(ElementObjectData &obj0, 
				   ElementObjectData &obj1)
388
389
390
391
392
393
394
    {
      TEST_EXIT_DBG(faceReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

      return faceReverseMode[make_pair(obj0, obj1)];
    }

395
396
397
398
399
400
    /// Returns true if there is periodic data.
    bool hasPeriodicData()
    {
      return (periodicVertices.size() != 0);
    }

401
402
403
404
405
406
407
408
    /// Returns true if the given boundary type is larger or equal to the smallest
    /// periodic boundary ID in mesh. See \ref smallestPeriodicBcType for more
    /// information.
    bool isValidPeriodicType(BoundaryType t) const
    {
      return (t >= smallestPeriodicBcType);
    }

409
410
411
412
413
414
415
416
417
418
    inline Element* getElementPtr(int index)
    {
      return macroElIndexMap[index];
    }

    inline int getElementType(int index)
    {
      return macroElIndexTypeMap[index];
    }

419
    /// Write the element database to disk.
420
    void serialize(ostream &out);
421
422
    
    /// Read the element database from disk.
423
    void deserialize(istream &in);
424

425
  protected:
426
427
428
429
430
431
432
433
434
    /** \brief
     * Adds an element to the object database. If the element is part of a
     * periodic boundary, all information about subobjects of the element on
     * this boundary are collected.
     *
     * \param[in]  elInfo    ElInfo object of the element. 
     */
    void addElement(ElInfo *elInfo);

435
    /// Adds the i-th DOF vertex of an element to the object database.
Thomas Witkowski's avatar
Thomas Witkowski committed
436
    void addVertex(Element *el, int ith);
437
438

    /// Adds the i-th edge of an element to the object database.
Thomas Witkowski's avatar
Thomas Witkowski committed
439
    void addEdge(Element *el, int ith);
440
441

    /// Adds the i-th face of an element to the object database.
Thomas Witkowski's avatar
Thomas Witkowski committed
442
    void addFace(Element *el, int ith);
443

444
445
446
447
448
449
450
451
452
453
    /** \brief
     * Creates final data of the periodic boundaries. Must be called after all
     * elements of the mesh are added to the object database. Then this functions
     * search for indirectly connected vertices in periodic boundaries. This is
     * only the case, if there are more than one boundary conditions. Then, e.g., 
     * in 2D, all edges of a square are iterectly connected. In 3D, if the macro 
     * mesh is a box, all eight vertex nodes and always four of the 12 edges are 
     * indirectly connected.
     */
    void createPeriodicData();
Thomas Witkowski's avatar
Thomas Witkowski committed
454
455
    
    void removePeriodicData();
456

457
458
459
460
461
462
    /// Creates on all boundaries the reverse mode flag.
    void createReverseModeData();

    BoundaryType getNewBoundaryType();

    BoundaryType provideConnectedPeriodicBoundary(BoundaryType b0, 
463
						  BoundaryType b1);
464
465

    /// Some auxiliary function to write the element object database to disk.
466
    void serialize(ostream &out, vector<ElementObjectData>& elVec);
467

468
    /// Some auxiliary function to read the element object database from disk.
469
    void deserialize(istream &in, vector<ElementObjectData>& elVec);
470

471
    /// Some auxiliary function to write the element object database to disk.
472
    void serialize(ostream &out, map<int, ElementObjectData>& data);
473

474
    /// Some auxiliary function to read the element object database from disk.
475
    void deserialize(istream &in, map<int, ElementObjectData>& data);
476

Thomas Witkowski's avatar
Thomas Witkowski committed
477
  private:
478
479
    const FiniteElemSpace* feSpace;

480
481
    /// The mesh that is used to store all its element information in 
    /// the database.
482
    Mesh *mesh;
483
    
484
    /// Maps to each vertex DOF all element objects that represent this vertex.
485
    map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
486
487

    /// Maps to each edge all element objects that represent this edge.
488
    map<DofEdge, vector<ElementObjectData> > edgeElements;
Thomas Witkowski's avatar
Thomas Witkowski committed
489

490
491
    /// Maps to each face all element objects that represent this edge.
    map<DofFace, vector<ElementObjectData> > faceElements;
492

493
494
    
    /// Maps to an element object the corresponding vertex DOF.
495
    map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
496
497

    /// Maps to an element object the corresponding edge.
498
    map<ElementObjectData, DofEdge> edgeLocalMap;
499
500

    /// Maps to an element object the corresponding face.
501
    map<ElementObjectData, DofFace> faceLocalMap;
502

503
   
504
505
    /// Defines to each vertex DOF a map that maps to each rank number the element
    /// objects that have this vertex DOF in common.
506
    map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank;
507

508
509
    /// Defines to each edge a map that maps to each rank number the element 
    /// objects that have this edge in common.
510
    map<DofEdge, map<int, ElementObjectData> > edgeInRank;
511

512
513
    /// Defines to each face a map that maps to each rank number the element 
    /// objects that have this face in common.
514
    map<DofFace, map<int, ElementObjectData> > faceInRank;
Thomas Witkowski's avatar
Thomas Witkowski committed
515

516
517

    /// Vertex iterator to iterate over \ref vertexInRank
518
    map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter;
519
520

    /// Edge iterator to iterate over \ref edgeInRank
521
    map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter;
522
523

    /// Face iterator to iterate over \ref faceInRank
524
    map<DofFace, map<int, ElementObjectData> >::iterator faceIter;
Thomas Witkowski's avatar
Thomas Witkowski committed
525

526
527
528
529
530

    /// Defines the geometrical iteration index of the iterators. I.e., the value
    /// is either VERTEX, EDGE or FACE and the corresponding element objects are
    /// traversed. The value CENTER is used to define a not defined states of the
    /// iterators, i.e., if no iteration is running.
Thomas Witkowski's avatar
Thomas Witkowski committed
531
    GeoIndex iterGeoPos;
532

533
    map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
534

535
    /// The following three data structures store periodic DOFs, edges and faces.
536
537
538
    PerBoundMap<DegreeOfFreedom>::type periodicVertices;
    PerBoundMap<DofEdge>::type periodicEdges;
    PerBoundMap<DofFace>::type periodicFaces;
539

540
541
542
543
544
545
546
    /// Defines the smallest boudary ID for periodic boundary conditions. This is
    /// required to distinguish between "real" periodic boundaries and periodic
    /// boundary IDs that are set by the parallel algorithm for indirectly 
    /// connected boundaries.
    BoundaryType smallestPeriodicBcType;

    /// Stores to each vertex all its periodic associations.
547
    map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
548

549
    /// Stores to each edge all its periodic associations.
550
551
552
553
554
    map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;

    map<pair<ElementObjectData, ElementObjectData>, bool> edgeReverseMode;

    map<pair<ElementObjectData, ElementObjectData>, bool> faceReverseMode;
555

556
557
    map<int, int> *macroElementRankMap;

558
559
560
561
562
    /// Maps to each macro element index a pointer to the corresponding element.
    map<int, Element*> macroElIndexMap;
    
    /// Maps to each macro element index the type of this element.
    map<int, int> macroElIndexTypeMap;
563
564

    MeshLevelData* levelData;
565
566
567
568
569
570

    /// If this variable is set to true, the mesh distributor removes all 
    /// periodic boundary conditions. The element neighbourhood relation is
    /// not changed. Thus, when using some domain decomposition method, this is
    /// a natural way to deal with periodic boundary conditions.
    bool removePeriodicBoundary;
Thomas Witkowski's avatar
Thomas Witkowski committed
571
572
573
574
575
  };

}

#endif