ElementObjectDatabase.h 18.2 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

#include <map>
#include <vector>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
30
#include <boost/container/flat_map.hpp>
Thomas Witkowski's avatar
Thomas Witkowski committed
31

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

namespace AMDiS {

41
42
  using namespace std;

43
44
  using boost::container::flat_map;

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

52
53

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

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

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

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

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

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



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

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

127
128
129
130
131
132
    /*
     * \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);
133

134
    void createMacroElementInfo(vector<MacroElement*> &mel);
135

136
137
138
    /// 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.
139
    void updateRankData();
140

Thomas Witkowski's avatar
bla    
Thomas Witkowski committed
141
142
143
    /// All data from the database is dropped. 
    void clear();

144
    /** \brief
145
146
147
     * 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.
148
     *
149
150
     * \param[in]  pos   Must be either VERTEX, EDGE or FACE and defines the
     *                   elements that should be traversed.
151
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
152
153
    bool iterate(GeoIndex pos)
    {
154
155
156
      // 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
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
209
210
211
212
213
214
      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;
    }


215
    /// Returns the data of the current iterator position.
216
    flat_map<int, ElementObjectData>& getIterateData()
Thomas Witkowski's avatar
Thomas Witkowski committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
    {
      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;
      }
    }

236
    /// Returns the rank owner of the current iterator position.
237
    int getIterateOwner(int level);
Thomas Witkowski's avatar
Thomas Witkowski committed
238

239
240
241
242
243
244
245
246
247
    /// 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);

248
    /// Returns the rank owner of the current iterator position.
249
    int getIterateMaxLevel();
250

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

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

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


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

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

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

289

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

315
316
317
318
319
320
    /// Returns, for a given vertex, a map that maps from rank numbers to 
    /// element data objects, which identify on the rank the element which 
    /// contains this vertex. If more than one element in one subdomain contains
    /// the vertex, the element with the highest element index is given. If the
    /// vertex is not contained in a rank's subdomain, it will not be considered
    /// in this mapping.
321
    flat_map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex)
322
323
324
325
    {
      return vertexInRank[vertex];
    }

326
327
328
329
330
331
    /// Returns, for a given edge, a map that maps from rank numbers to 
    /// element data objects, which identify on the rank the element which 
    /// contains this edge. If more than one element in one subdomain contains
    /// the edge, the element with the highest element index is given. If the
    /// edge is not contained in a rank's subdomain, it will not be considered
    /// in this mapping.
332
    flat_map<int, ElementObjectData>& getElementsInRank(DofEdge edge)
333
334
335
336
    {
      return edgeInRank[edge];
    }

337
338
339
340
    /// Returns, for a given face, a map that maps from rank numbers to 
    /// element data objects, which identify on the rank the element which 
    /// contains this face. If the face is not contained in a rank's subdomain, 
    /// it will not be considered in this mapping.
341
    flat_map<int, ElementObjectData>& getElementsInRank(DofFace face)
342
343
344
345
    {
      return faceInRank[face];
    }

346
    /// Returns to an element object data the appropriate vertex DOF.
347
348
    DegreeOfFreedom getVertexLocalMap(ElementObjectData &data)
    {
349
350
      TEST_EXIT_DBG(vertexLocalMap.count(data))("Should not happen!\n");

351
352
353
      return vertexLocalMap[data];
    }

354
    /// Returns to an element object data the appropriate edge.
355
356
    DofEdge getEdgeLocalMap(ElementObjectData &data)
    {
357
358
      TEST_EXIT_DBG(edgeLocalMap.count(data))("Should not happen!\n");

359
360
361
      return edgeLocalMap[data];
    }

362
    /// Returns to an element object data the appropriate face.
363
364
    DofFace getFaceLocalMap(ElementObjectData &data)
    {
365
366
      TEST_EXIT_DBG(faceLocalMap.count(data))("Should not happen!\n");

367
368
369
      return faceLocalMap[data];
    }

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    PerBoundMap<DegreeOfFreedom>::type& getPeriodicVertices()
    {
      return periodicVertices;
    }

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

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

385
386
    inline bool getEdgeReverseMode(ElementObjectData &obj0, 
				   ElementObjectData &obj1)
387
    {
388
389
390
      if (mesh->getDim() == 2)
	return true;

391
392
      if (edgeReverseMode.empty())
	return false;
393

394
      return static_cast<bool>(edgeReverseMode.count(make_pair(obj0, obj1)));
395
396
    }

397
398
    inline bool getFaceReverseMode(ElementObjectData &obj0, 
				   ElementObjectData &obj1)
399
    {
400
401
      if (faceReverseMode.empty())
	return false;
402

403
      return static_cast<bool>(faceReverseMode.count(make_pair(obj0, obj1)));
404
405
    }

406
407
408
409
410
411
    /// Returns true if there is periodic data.
    bool hasPeriodicData()
    {
      return (periodicVertices.size() != 0);
    }

412
413
414
415
416
417
418
419
    /// 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);
    }

420
421
422
423
424
425
426
427
428
429
    inline Element* getElementPtr(int index)
    {
      return macroElIndexMap[index];
    }

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

Thomas Witkowski's avatar
Thomas Witkowski committed
430
431
432
433
434
435
436
    void setData(map<int, int> &rankMap,
		MeshLevelData& ld)
    {
      macroElementRankMap = &rankMap;
      levelData = &ld;
    }

437
    /// Write the element database to disk.
438
    void serialize(ostream &out);
439
440
    
    /// Read the element database from disk.
441
    void deserialize(istream &in);
442

443
444
445
    /// Returns the estimated memory usage of an object of this class.
    unsigned long calculateMemoryUsage();

446
  protected:
447
448
449
450
451
452
453
454
455
    /** \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);

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

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

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

465
466
467
468
469
470
471
    /// 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.
472
    void createPeriodicData();
Thomas Witkowski's avatar
Thomas Witkowski committed
473
    
474
475
476
477
478
479
    /// Creates on all boundaries the reverse mode flag.
    void createReverseModeData();

    BoundaryType getNewBoundaryType();

    BoundaryType provideConnectedPeriodicBoundary(BoundaryType b0, 
480
						  BoundaryType b1);
481
482

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

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

488
    /// Some auxiliary function to write the element object database to disk.
489
    void serialize(ostream &out, flat_map<int, ElementObjectData>& data);
490

491
    /// Some auxiliary function to read the element object database from disk.
492
    void deserialize(istream &in, flat_map<int, ElementObjectData>& data);
493

494
    int getOwner(vector<ElementObjectData>& objData, int level);
Thomas Witkowski's avatar
Thomas Witkowski committed
495
  private:
496
497
    const FiniteElemSpace* feSpace;

498
499
    /// The mesh that is used to store all its element information in 
    /// the database.
500
    Mesh *mesh;
501
    
502
    /// Maps to each vertex DOF all element objects that represent this vertex.
503
    map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
504
505

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

508
509
    /// Maps to each face all element objects that represent this edge.
    map<DofFace, vector<ElementObjectData> > faceElements;
510

511
512
    
    /// Maps to an element object the corresponding vertex DOF.
513
    flat_map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
514
515

    /// Maps to an element object the corresponding edge.
516
    flat_map<ElementObjectData, DofEdge> edgeLocalMap;
517
518

    /// Maps to an element object the corresponding face.
519
    flat_map<ElementObjectData, DofFace> faceLocalMap;
520

521
   
522
523
    /// Defines to each vertex DOF a map that maps to each rank number the element
    /// objects that have this vertex DOF in common.
524
    flat_map<DegreeOfFreedom, flat_map<int, ElementObjectData> > vertexInRank;
525

526
527
    /// Defines to each edge a map that maps to each rank number the element 
    /// objects that have this edge in common.
528
    flat_map<DofEdge, flat_map<int, ElementObjectData> > edgeInRank;
529

530
531
    /// Defines to each face a map that maps to each rank number the element 
    /// objects that have this face in common.
532
    flat_map<DofFace, flat_map<int, ElementObjectData> > faceInRank;
Thomas Witkowski's avatar
Thomas Witkowski committed
533

534
535

    /// Vertex iterator to iterate over \ref vertexInRank
536
    flat_map<DegreeOfFreedom, flat_map<int, ElementObjectData> >::iterator vertexIter;
537
538

    /// Edge iterator to iterate over \ref edgeInRank
539
    flat_map<DofEdge, flat_map<int, ElementObjectData> >::iterator edgeIter;
540
541

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

544
545
546
547
548

    /// 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
549
    GeoIndex iterGeoPos;
550

551
    map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
552

553
    /// The following three data structures store periodic DOFs, edges and faces.
554
555
556
    PerBoundMap<DegreeOfFreedom>::type periodicVertices;
    PerBoundMap<DofEdge>::type periodicEdges;
    PerBoundMap<DofFace>::type periodicFaces;
557

558
559
560
561
562
563
564
    /// 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.
565
    map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
566

567
    /// Stores to each edge all its periodic associations.
568
569
    map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;

570
571
    /// Stores all interior edge boundaries which have reverse mode enabled.
    std::set<pair<ElementObjectData, ElementObjectData> > edgeReverseMode;
572

573
574
    /// Stores all interior face boundaries which have reverse mode enabled.
    std::set<pair<ElementObjectData, ElementObjectData> > faceReverseMode;
575

576
577
    map<int, int> *macroElementRankMap;

578
579
580
581
582
    /// 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;
583
584

    MeshLevelData* levelData;
Thomas Witkowski's avatar
Thomas Witkowski committed
585
586
587
588
589
  };

}

#endif