ElementObjectDatabase.h 18.6 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
62
    int ithObject;
    
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
      : mesh(NULL),
107
	iterGeoPos(CENTER)
Thomas Witkowski's avatar
Thomas Witkowski committed
108
109
    {}

110

111
112
    /// Set the mesh that should be used for the database.
    void setMesh(Mesh *m)
Thomas Witkowski's avatar
Thomas Witkowski committed
113
    {
114
      mesh = m;
115
116
117
    }


118
    /** \brief
119
120
121
     * 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.
122
123
124
125
126
127
128
129
130
     *
     * \param[in]  elInfo    ElInfo object of the element. 
     */
    void addElement(ElInfo *elInfo);


    /** \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
131
132
133
134
135
     * 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.
136
     */
137
    void createPeriodicData(const FiniteElemSpace *feSpace);
138
139
140


    /** \brief
141
142
143
     * 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.
144
     *
145
146
     * \param[in]  macroElementRankMap   Maps to each macro element of the mesh
     *                                   the rank that owns this macro element.
147
     */
148
149
    void createRankData(map<int, int>& macroElementRankMap,
			MeshLevelData& levelData);
Thomas Witkowski's avatar
Thomas Witkowski committed
150

151

152
153
154
155
156
157
158
159
160
161
162
163
164
    /** \brief
     * Creates on all boundaries the reverse mode flag.
     *
     * \param[in] feSpace         An arbitrary FE space defined on the mesh. 
     *                            Is used to get the orientation of the DOFs on 
     *                            elements.
     * \param[in] elIndexMap      Maps an element index to the pointer to the 
     *                            element.
     * \param[in] elIndexTypeMap  Maps an element index to its type id (only
     *                            relevant in 3D).
     */
    void createReverseModeData(const FiniteElemSpace* feSpace,
			       map<int, Element*> &elIndexMap,
165
166
			       map<int, int> &elIndexTypeMap);

167

168
    /** \brief
169
170
171
     * 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.
172
     *
173
174
     * \param[in]  pos   Must be either VERTEX, EDGE or FACE and defines the
     *                   elements that should be traversed.
175
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
176
177
    bool iterate(GeoIndex pos)
    {
178
179
180
      // 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
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
      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;
    }


239
    /// Returns the data of the current iterator position.
240
    map<int, ElementObjectData>& getIterateData()
Thomas Witkowski's avatar
Thomas Witkowski committed
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
    {
      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;
      }
    }


261
    /// Returns the rank owner of the current iterator position.
262
    int getIterateOwner()
Thomas Witkowski's avatar
Thomas Witkowski committed
263
264
265
    {
      switch (iterGeoPos) {
      case VERTEX:
266
	return vertexOwner[vertexIter->first];
Thomas Witkowski's avatar
Thomas Witkowski committed
267
268
	break;
      case EDGE:
269
	return edgeOwner[edgeIter->first];
Thomas Witkowski's avatar
Thomas Witkowski committed
270
271
	break;
      case FACE:
272
	return faceOwner[faceIter->first];
Thomas Witkowski's avatar
Thomas Witkowski committed
273
274
275
276
277
278
279
280
281
	break;
      default:
	ERROR_EXIT("Should not happen!\n");

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

282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
    /// Returns the rank owner of the current iterator position.
    int getIterateMaxLevel()
    {
      switch (iterGeoPos) {
      case VERTEX:
	return vertexMaxLevel[vertexIter->first];
	break;
      case EDGE:
	return edgeMaxLevel[edgeIter->first];
	break;
      case FACE:
	return faceMaxLevel[faceIter->first];
	break;
      default:
	ERROR_EXIT("Should not happen!\n");

	// Will never be reached, just to avoid compiler warnings.
	return -1;
      }
    }
302

303
    /// Returns the rank owner of a vertex DOF.
304
    int getOwner(DegreeOfFreedom vertex)
Thomas Witkowski's avatar
Thomas Witkowski committed
305
    {
306
      return vertexOwner[vertex];
Thomas Witkowski's avatar
Thomas Witkowski committed
307
308
    }

309
    /// Returns the rank owner of an edge.
310
    int getOwner(DofEdge edge)
Thomas Witkowski's avatar
Thomas Witkowski committed
311
    {
312
      return edgeOwner[edge];
Thomas Witkowski's avatar
Thomas Witkowski committed
313
314
    }

315
    /// Returns the rank owner of an face.
316
    int getOwner(DofFace face, int level)
Thomas Witkowski's avatar
Thomas Witkowski committed
317
    {
318
      return faceOwner[face];
Thomas Witkowski's avatar
Thomas Witkowski committed
319
320
    }

321

322
    /// Checks if a given vertex DOF is in a given rank.
323
324
325
326
327
    int isInRank(DegreeOfFreedom vertex, int rank)
    {
      return (vertexInRank[vertex].count(rank));
    }

328
    /// Checks if a given edge is in a given rank.
329
330
331
332
333
    int isInRank(DofEdge edge, int rank)
    {
      return (edgeInRank[edge].count(rank));
    }

334
    /// Checks if a given face is in a given rank.
335
336
337
338
339
340
    int isInRank(DofFace face, int rank)
    {
      return (faceInRank[face].count(rank));
    }


341
342
    /// Returns a vector with all macro elements that have a given vertex DOF 
    /// in common.
343
    vector<ElementObjectData>& getElements(DegreeOfFreedom vertex)
Thomas Witkowski's avatar
Thomas Witkowski committed
344
345
346
347
    {
      return vertexElements[vertex];
    }

348
    /// Returns a vector with all macro elements that have a given edge in common.
349
    vector<ElementObjectData>& getElements(DofEdge edge)
Thomas Witkowski's avatar
Thomas Witkowski committed
350
351
352
353
    {
      return edgeElements[edge];
    }

354
    /// Returns a vector with all macro elements that have a given face in common.
355
    vector<ElementObjectData>& getElements(DofFace face)
Thomas Witkowski's avatar
Thomas Witkowski committed
356
357
358
359
    {
      return faceElements[face];
    }

360

361
362
    /// Returns a vector with all macro elements that have a given vertex DOF 
    /// in common.
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    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];
    }


387
388
389
    
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given vertex DOF in common.
390
    map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex)
391
392
393
394
    {
      return vertexInRank[vertex];
    }

395
396
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given edge in common.
397
    map<int, ElementObjectData>& getElementsInRank(DofEdge edge)
398
399
400
401
    {
      return edgeInRank[edge];
    }

402
403
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given face in common.
404
    map<int, ElementObjectData>& getElementsInRank(DofFace face)
405
406
407
408
    {
      return faceInRank[face];
    }

409
    /// Returns to an element object data the appropriate vertex DOF.
410
411
    DegreeOfFreedom getVertexLocalMap(ElementObjectData &data)
    {
412
413
      TEST_EXIT_DBG(vertexLocalMap.count(data))("Should not happen!\n");

414
415
416
      return vertexLocalMap[data];
    }

417
    /// Returns to an element object data the appropriate edge.
418
419
    DofEdge getEdgeLocalMap(ElementObjectData &data)
    {
420
421
      TEST_EXIT_DBG(edgeLocalMap.count(data))("Should not happen!\n");

422
423
424
      return edgeLocalMap[data];
    }

425
    /// Returns to an element object data the appropriate face.
426
427
    DofFace getFaceLocalMap(ElementObjectData &data)
    {
428
429
      TEST_EXIT_DBG(faceLocalMap.count(data))("Should not happen!\n");

430
431
432
      return faceLocalMap[data];
    }

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
    PerBoundMap<DegreeOfFreedom>::type& getPeriodicVertices()
    {
      return periodicVertices;
    }

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

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

448
449
    inline bool getEdgeReverseMode(ElementObjectData &obj0, 
				   ElementObjectData &obj1)
450
    {
451
452
453
      if (mesh->getDim() == 2)
	return true;

454
455
456
457
458
459
      TEST_EXIT_DBG(edgeReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

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

460
461
    inline bool getFaceReverseMode(ElementObjectData &obj0, 
				   ElementObjectData &obj1)
462
463
464
465
466
467
468
    {
      TEST_EXIT_DBG(faceReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

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

469
470
471
472
473
474
    /// Returns true if there is periodic data.
    bool hasPeriodicData()
    {
      return (periodicVertices.size() != 0);
    }

475
476
477
478
479
480
481
482
    /// 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);
    }

483
    /// Write the element database to disk.
484
    void serialize(ostream &out);
485
486
    
    /// Read the element database from disk.
487
    void deserialize(istream &in);
488

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
  protected:
    /// Adds the i-th DOF vertex of an element to the object database.
    void addVertex(Element *el, int ith)
    {
      DegreeOfFreedom vertex = el->getDof(ith, 0);
      int elIndex = el->getIndex();
      ElementObjectData elObj(elIndex, ith);

      vertexElements[vertex].push_back(elObj);
      vertexLocalMap[elObj] = vertex;
    }

    /// Adds the i-th edge of an element to the object database.
    void addEdge(Element *el, int ith)
    {
      DofEdge edge = el->getEdge(ith);
      int elIndex = el->getIndex();
      ElementObjectData elObj(elIndex, ith);

      edgeElements[edge].push_back(elObj);
      edgeLocalMap[elObj] = edge;
    }

    /// Adds the i-th face of an element to the object database.
    void addFace(Element *el, int ith)
    {
      DofFace face = el->getFace(ith);
      int elIndex = el->getIndex();
      ElementObjectData elObj(elIndex, ith);

      faceElements[face].push_back(elObj);
      faceLocalMap[elObj] = face;
    }

523
    BoundaryType getNewBoundaryType(DOFAdmin *admin);
524

525
526
527
    BoundaryType provideConnectedPeriodicBoundary(DOFAdmin *admin,
						  BoundaryType b0, 
						  BoundaryType b1);
528
529

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

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

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
541
  private:
542
543
    /// The mesh that is used to store all its element information in 
    /// the database.
544
545
546
    Mesh *mesh;

    /// Maps to each vertex DOF all element objects that represent this vertex.
547
    map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
548
549

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

552
553
    /// Maps to each face all element objects that represent this edge.
    map<DofFace, vector<ElementObjectData> > faceElements;
554

555
556
    
    /// Maps to an element object the corresponding vertex DOF.
557
    map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
558
559

    /// Maps to an element object the corresponding edge.
560
    map<ElementObjectData, DofEdge> edgeLocalMap;
561
562

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

565
    /// Defines for all vertex DOFs the rank that ownes this vertex DOF.
566
    map<DegreeOfFreedom, int> vertexOwner;
567
568

    /// Defines for all edges the rank that ownes this edge.
569
    map<DofEdge, int> edgeOwner;
570
571

    /// Defines for all faces the rank that ownes this face.
572
    map<DofFace, int> faceOwner;
Thomas Witkowski's avatar
Thomas Witkowski committed
573

574
575
576
577
578
579
580
    
    map<DegreeOfFreedom, int> vertexMaxLevel;

    map<DofEdge, int> edgeMaxLevel;

    map<DofFace, int> faceMaxLevel;

581

582
583
    /// Defines to each vertex DOF a map that maps to each rank number the element
    /// objects that have this vertex DOF in common.
584
    map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank;
585

586
587
    /// Defines to each edge a map that maps to each rank number the element 
    /// objects that have this edge in common.
588
    map<DofEdge, map<int, ElementObjectData> > edgeInRank;
589

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

594
595

    /// Vertex iterator to iterate over \ref vertexInRank
596
    map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter;
597
598

    /// Edge iterator to iterate over \ref edgeInRank
599
    map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter;
600
601

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

604
605
606
607
608

    /// 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
609
    GeoIndex iterGeoPos;
610

611
    map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
612

613
    /// The following three data structures store periodic DOFs, edges and faces.
614
615
616
    PerBoundMap<DegreeOfFreedom>::type periodicVertices;
    PerBoundMap<DofEdge>::type periodicEdges;
    PerBoundMap<DofFace>::type periodicFaces;
617

618
619
620
621
622
623
624
    /// 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.
625
    map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
626

627
    /// Stores to each edge all its periodic associations.
628
629
630
631
632
    map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;

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

    map<pair<ElementObjectData, ElementObjectData>, bool> faceReverseMode;
Thomas Witkowski's avatar
Thomas Witkowski committed
633
634
635
636
637
  };

}

#endif