ElementObjectDatabase.h 18 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 "Containers.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
32
33
#include "Global.h"
#include "Boundary.h"
34
#include "Serializer.h"
35
#include "FiniteElemSpace.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
36
37
38

namespace AMDiS {

39
40
  using namespace std;

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

48
49

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

    /// Index of the element this object is part of.
Thomas Witkowski's avatar
Thomas Witkowski committed
57
58
    int elIndex;
    
59
    /// Index of the object within the element.
Thomas Witkowski's avatar
Thomas Witkowski committed
60
61
    int ithObject;
    
62
    /// Write this element object to disk.
63
    void serialize(ostream &out) const
64
65
66
67
68
    {
      SerUtil::serialize(out, elIndex);
      SerUtil::serialize(out, ithObject);
    }

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

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

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



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

109

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


117
    /** \brief
118
119
120
     * 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.
121
122
123
124
125
126
127
128
129
     *
     * \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
130
131
132
133
134
     * 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.
135
     */
136
    void createPeriodicData(const FiniteElemSpace *feSpace);
137
138
139


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

149

150
151
152
153
154
155
156
157
158
159
160
161
162
    /** \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,
163
164
			       map<int, int> &elIndexTypeMap);

165

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


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


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

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

280

281
    /// Returns the rank owner of a vertex DOF.
Thomas Witkowski's avatar
Thomas Witkowski committed
282
283
284
285
286
    int getOwner(DegreeOfFreedom vertex)
    {
      return vertexOwner[vertex];
    }

287
    /// Returns the rank owner of an edge.
Thomas Witkowski's avatar
Thomas Witkowski committed
288
289
290
291
292
    int getOwner(DofEdge edge)
    {
      return edgeOwner[edge];
    }

293
    /// Returns the rank owner of an face.
Thomas Witkowski's avatar
Thomas Witkowski committed
294
295
296
297
298
    int getOwner(DofFace face)
    {
      return faceOwner[face];
    }

299

300
    /// Checks if a given vertex DOF is in a given rank.
301
302
303
304
305
    int isInRank(DegreeOfFreedom vertex, int rank)
    {
      return (vertexInRank[vertex].count(rank));
    }

306
    /// Checks if a given edge is in a given rank.
307
308
309
310
311
    int isInRank(DofEdge edge, int rank)
    {
      return (edgeInRank[edge].count(rank));
    }

312
    /// Checks if a given face is in a given rank.
313
314
315
316
317
318
    int isInRank(DofFace face, int rank)
    {
      return (faceInRank[face].count(rank));
    }


319
320
    /// Returns a vector with all macro elements that have a given vertex DOF 
    /// in common.
321
    vector<ElementObjectData>& getElements(DegreeOfFreedom vertex)
Thomas Witkowski's avatar
Thomas Witkowski committed
322
323
324
325
    {
      return vertexElements[vertex];
    }

326
    /// Returns a vector with all macro elements that have a given edge in common.
327
    vector<ElementObjectData>& getElements(DofEdge edge)
Thomas Witkowski's avatar
Thomas Witkowski committed
328
329
330
331
    {
      return edgeElements[edge];
    }

332
    /// Returns a vector with all macro elements that have a given face in common.
333
    vector<ElementObjectData>& getElements(DofFace face)
Thomas Witkowski's avatar
Thomas Witkowski committed
334
335
336
337
    {
      return faceElements[face];
    }

338

339
340
    /// Returns a vector with all macro elements that have a given vertex DOF 
    /// in common.
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    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];
    }


365
366
367
    
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given vertex DOF in common.
368
    map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex)
369
370
371
372
    {
      return vertexInRank[vertex];
    }

373
374
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given edge in common.
375
    map<int, ElementObjectData>& getElementsInRank(DofEdge edge)
376
377
378
379
    {
      return edgeInRank[edge];
    }

380
381
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given face in common.
382
    map<int, ElementObjectData>& getElementsInRank(DofFace face)
383
384
385
386
    {
      return faceInRank[face];
    }

387
    /// Returns to an element object data the appropriate vertex DOF.
388
389
    DegreeOfFreedom getVertexLocalMap(ElementObjectData &data)
    {
390
391
      TEST_EXIT_DBG(vertexLocalMap.count(data))("Should not happen!\n");

392
393
394
      return vertexLocalMap[data];
    }

395
    /// Returns to an element object data the appropriate edge.
396
397
    DofEdge getEdgeLocalMap(ElementObjectData &data)
    {
398
399
      TEST_EXIT_DBG(edgeLocalMap.count(data))("Should not happen!\n");

400
401
402
      return edgeLocalMap[data];
    }

403
    /// Returns to an element object data the appropriate face.
404
405
    DofFace getFaceLocalMap(ElementObjectData &data)
    {
406
407
      TEST_EXIT_DBG(faceLocalMap.count(data))("Should not happen!\n");

408
409
410
      return faceLocalMap[data];
    }

411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
    PerBoundMap<DegreeOfFreedom>::type& getPeriodicVertices()
    {
      return periodicVertices;
    }

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

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

426
427
    inline bool getEdgeReverseMode(ElementObjectData &obj0, 
				   ElementObjectData &obj1)
428
    {
429
430
431
      if (mesh->getDim() == 2)
	return true;

432
433
434
435
436
437
      TEST_EXIT_DBG(edgeReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

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

438
439
    inline bool getFaceReverseMode(ElementObjectData &obj0, 
				   ElementObjectData &obj1)
440
441
442
443
444
445
446
    {
      TEST_EXIT_DBG(faceReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

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

447
448
449
450
451
452
    /// Returns true if there is periodic data.
    bool hasPeriodicData()
    {
      return (periodicVertices.size() != 0);
    }

453
454
455
456
457
458
459
460
    /// 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);
    }

461
    /// Write the element database to disk.
462
    void serialize(ostream &out);
463
464
    
    /// Read the element database from disk.
465
    void deserialize(istream &in);
466

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
  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;
    }

501
    BoundaryType getNewBoundaryType(DOFAdmin *admin);
502

503
504
505
    BoundaryType provideConnectedPeriodicBoundary(DOFAdmin *admin,
						  BoundaryType b0, 
						  BoundaryType b1);
506
507

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

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

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
519
  private:
520
521
    /// The mesh that is used to store all its element information in 
    /// the database.
522
523
524
    Mesh *mesh;

    /// Maps to each vertex DOF all element objects that represent this vertex.
525
    map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
526
527

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

530
531
    /// Maps to each face all element objects that represent this edge.
    map<DofFace, vector<ElementObjectData> > faceElements;
532

533
534
    
    /// Maps to an element object the corresponding vertex DOF.
535
    map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
536
537

    /// Maps to an element object the corresponding edge.
538
    map<ElementObjectData, DofEdge> edgeLocalMap;
539
540

    /// Maps to an element object the corresponding face.
541
    map<ElementObjectData, DofFace> faceLocalMap;
542
543


544
    /// Defines for all vertex DOFs the rank that ownes this vertex DOF.
545
    map<DegreeOfFreedom, int> vertexOwner;
546
547

    /// Defines for all edges the rank that ownes this edge.
548
    map<DofEdge, int> edgeOwner;
549
550

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

553

554
555
    /// Defines to each vertex DOF a map that maps to each rank number the element
    /// objects that have this vertex DOF in common.
556
    map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank;
557

558
559
    /// Defines to each edge a map that maps to each rank number the element 
    /// objects that have this edge in common.
560
    map<DofEdge, map<int, ElementObjectData> > edgeInRank;
561

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

566
567

    /// Vertex iterator to iterate over \ref vertexInRank
568
    map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter;
569
570

    /// Edge iterator to iterate over \ref edgeInRank
571
    map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter;
572
573

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

576
577
578
579
580

    /// 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
581
    GeoIndex iterGeoPos;
582

583
    map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
584

585
    /// The following three data structures store periodic DOFs, edges and faces.
586
587
588
    PerBoundMap<DegreeOfFreedom>::type periodicVertices;
    PerBoundMap<DofEdge>::type periodicEdges;
    PerBoundMap<DofFace>::type periodicFaces;
589

590
591
592
593
594
595
596
    /// 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.
597
    map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
598

599
    /// Stores to each edge all its periodic associations.
600
601
602
603
604
    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
605
606
607
608
609
  };

}

#endif