ElementObjectDatabase.h 17.1 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),
54
	ithObject(b)
Thomas Witkowski's avatar
Thomas Witkowski committed
55
    {}
56
57

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

63
    /// Write this element object to disk.
64
    void serialize(ostream &out) const
65
66
67
68
69
    {
      SerUtil::serialize(out, elIndex);
      SerUtil::serialize(out, ithObject);
    }

70
    /// Read this element object from disk.
71
    void deserialize(istream &in)
72
73
74
75
76
    {
      SerUtil::deserialize(in, elIndex);
      SerUtil::deserialize(in, ithObject);
    }

77
    /// Compare this element object with another one.
78
79
    bool operator==(ElementObjectData& cmp) const
    {
80
      return (elIndex == cmp.elIndex && ithObject == cmp.ithObject);
81
82
    }

83
    /// Define a strict order on element objects.
84
85
    bool operator<(const ElementObjectData& rhs) const
    {
86
87
      return (elIndex < rhs.elIndex || 
	      (elIndex == rhs.elIndex && ithObject < rhs.ithObject));
88
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
89
90
91
92
  };



93
94
  /** \brief
   * This class is a database of element objects. An element object is either a
95
96
97
98
99
100
101
   * 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.
102
   */
103
  class ElementObjectDatabase {
Thomas Witkowski's avatar
Thomas Witkowski committed
104
  public:
105
    ElementObjectDatabase()
106
107
      : feSpace(NULL),
	mesh(NULL),
108
109
	iterGeoPos(CENTER),
	macroElementRankMap(NULL),
110
111
	levelData(NULL)
    {}
Thomas Witkowski's avatar
Thomas Witkowski committed
112

113
    void setFeSpace(const FiniteElemSpace *fe)
Thomas Witkowski's avatar
Thomas Witkowski committed
114
    {
115
116
117
118
119
120
121
      feSpace = fe;
      mesh = feSpace->getMesh();
    }
  
    Mesh* getMesh()
    {
      return mesh;
122
123
    }

124
125
126
127
128
129
    /*
     * \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);
130

131
    void createMacroElementInfo(vector<MacroElement*> &mel);
132

133
134
135
    /// 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.
136
    void updateRankData();
137

138
    /** \brief
139
140
141
     * 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.
142
     *
143
144
     * \param[in]  pos   Must be either VERTEX, EDGE or FACE and defines the
     *                   elements that should be traversed.
145
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
146
147
    bool iterate(GeoIndex pos)
    {
148
149
150
      // 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
151
152
153
154
155
156
157
158
159
160
161
162
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
      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;
    }


209
    /// Returns the data of the current iterator position.
210
    map<int, ElementObjectData>& getIterateData()
Thomas Witkowski's avatar
Thomas Witkowski committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    {
      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;
      }
    }

230
    /// Returns the rank owner of the current iterator position.
231
    int getIterateOwner(int level);
Thomas Witkowski's avatar
Thomas Witkowski committed
232

233
234
235
236
237
238
239
240
241
    /// Returns the owner of a macro element vertex.
    int getOwner(DegreeOfFreedom vertex, int level);

    /// Returns the owner of a macro element edge.
    int getOwner(DofEdge edge, int level);
	
    /// Returns the owner of a macro element face.
    int getOwner(DofFace face, int level);

242
    /// Returns the rank owner of the current iterator position.
243
    int getIterateMaxLevel();
244

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

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

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


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

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

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

283

284
285
    /// Returns a vector with all macro elements that have a given vertex DOF 
    /// in common.
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    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];
    }


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

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

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

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

337
338
339
      return vertexLocalMap[data];
    }

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

345
346
347
      return edgeLocalMap[data];
    }

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

353
354
355
      return faceLocalMap[data];
    }

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

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

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

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

377
378
379
380
381
382
      TEST_EXIT_DBG(edgeReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

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

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

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

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

398
399
400
401
402
403
404
405
    /// 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);
    }

406
407
408
409
410
411
412
413
414
415
    inline Element* getElementPtr(int index)
    {
      return macroElIndexMap[index];
    }

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

Thomas Witkowski's avatar
Thomas Witkowski committed
416
417
418
419
420
421
422
    void setData(map<int, int> &rankMap,
		MeshLevelData& ld)
    {
      macroElementRankMap = &rankMap;
      levelData = &ld;
    }

423
    /// Write the element database to disk.
424
    void serialize(ostream &out);
425
426
    
    /// Read the element database from disk.
427
    void deserialize(istream &in);
428

429
430
431
    /// Returns the estimated memory usage of an object of this class.
    unsigned long calculateMemoryUsage();

432
  protected:
433
434
435
436
437
438
439
440
441
    /** \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);

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

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

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

451
452
453
454
455
456
457
458
459
460
    /** \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
461
    
462
463
464
465
466
467
    /// Creates on all boundaries the reverse mode flag.
    void createReverseModeData();

    BoundaryType getNewBoundaryType();

    BoundaryType provideConnectedPeriodicBoundary(BoundaryType b0, 
468
						  BoundaryType b1);
469
470

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

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

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

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

482
    int getOwner(vector<ElementObjectData>& objData, int level);
Thomas Witkowski's avatar
Thomas Witkowski committed
483
  private:
484
485
    const FiniteElemSpace* feSpace;

486
487
    /// The mesh that is used to store all its element information in 
    /// the database.
488
    Mesh *mesh;
489
    
490
    /// Maps to each vertex DOF all element objects that represent this vertex.
491
    map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
492
493

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

496
497
    /// Maps to each face all element objects that represent this edge.
    map<DofFace, vector<ElementObjectData> > faceElements;
498

499
500
    
    /// Maps to an element object the corresponding vertex DOF.
501
    map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
502
503

    /// Maps to an element object the corresponding edge.
504
    map<ElementObjectData, DofEdge> edgeLocalMap;
505
506

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

509
   
510
511
    /// Defines to each vertex DOF a map that maps to each rank number the element
    /// objects that have this vertex DOF in common.
512
    map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank;
513

514
515
    /// Defines to each edge a map that maps to each rank number the element 
    /// objects that have this edge in common.
516
    map<DofEdge, map<int, ElementObjectData> > edgeInRank;
517

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

522
523

    /// Vertex iterator to iterate over \ref vertexInRank
524
    map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter;
525
526

    /// Edge iterator to iterate over \ref edgeInRank
527
    map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter;
528
529

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

532
533
534
535
536

    /// 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
537
    GeoIndex iterGeoPos;
538

539
    map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
540

541
    /// The following three data structures store periodic DOFs, edges and faces.
542
543
544
    PerBoundMap<DegreeOfFreedom>::type periodicVertices;
    PerBoundMap<DofEdge>::type periodicEdges;
    PerBoundMap<DofFace>::type periodicFaces;
545

546
547
548
549
550
551
552
    /// 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.
553
    map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
554

555
    /// Stores to each edge all its periodic associations.
556
557
558
559
560
    map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;

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

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

562
563
    map<int, int> *macroElementRankMap;

564
565
566
567
568
    /// 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;
569
570

    MeshLevelData* levelData;
Thomas Witkowski's avatar
Thomas Witkowski committed
571
572
573
574
575
  };

}

#endif