ElementObjectData.h 15 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
22
23
24
25
26
27
28
29
30
31
32

/** \file ElementObjectData.h */

#ifndef AMDIS_ELEMENTOBJECTDATA_H
#define AMDIS_ELEMENTOBJECTDATA_H

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

#include "Global.h"
#include "Boundary.h"
33
#include "Serializer.h"
34
#include "FiniteElemSpace.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
35
36
37

namespace AMDiS {

38
39
  using namespace std;

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

47
48

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

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

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

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

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



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

109

110
111
112
    /// Set the finite element space that should be used for the database (especially
    /// the mesh is of interest).
    void setFeSpace(FiniteElemSpace *fe)
Thomas Witkowski's avatar
Thomas Witkowski committed
113
    {
114
115
      feSpace = fe;
      mesh = feSpace->getMesh();
116
117
118
    }


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    /** \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);


    /** \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 interectly 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 iterectly 
     * connected.
     */
    void createPeriodicData();


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

151

152
153
154
155
156
157
158
159
    /** \brief
     * 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.
     *
     * \param[in]  pos   Must be either VERTEX, EDGE or FACE and defines the elements
     *                   that should be traversed.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
160
161
    bool iterate(GeoIndex pos)
    {
162
163
164
      // 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
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
221
222
      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;
    }


223
    /// Returns the data of the current iterator position.
224
    map<int, ElementObjectData>& getIterateData()
Thomas Witkowski's avatar
Thomas Witkowski committed
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    {
      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;
      }
    }


245
    /// Returns the rank owner of the current iterator position.
Thomas Witkowski's avatar
Thomas Witkowski committed
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    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;
      }
    }

266

267
    /// Returns the rank owner of a vertex DOF.
Thomas Witkowski's avatar
Thomas Witkowski committed
268
269
270
271
272
    int getOwner(DegreeOfFreedom vertex)
    {
      return vertexOwner[vertex];
    }

273
    /// Returns the rank owner of an edge.
Thomas Witkowski's avatar
Thomas Witkowski committed
274
275
276
277
278
    int getOwner(DofEdge edge)
    {
      return edgeOwner[edge];
    }

279
    /// Returns the rank owner of an face.
Thomas Witkowski's avatar
Thomas Witkowski committed
280
281
282
283
284
    int getOwner(DofFace face)
    {
      return faceOwner[face];
    }

285

286
    /// Checks if a given vertex DOF is in a given rank.
287
288
289
290
291
    int isInRank(DegreeOfFreedom vertex, int rank)
    {
      return (vertexInRank[vertex].count(rank));
    }

292
    /// Checks if a given edge is in a given rank.
293
294
295
296
297
    int isInRank(DofEdge edge, int rank)
    {
      return (edgeInRank[edge].count(rank));
    }

298
    /// Checks if a given face is in a given rank.
299
300
301
302
303
304
    int isInRank(DofFace face, int rank)
    {
      return (faceInRank[face].count(rank));
    }


305
    /// Returns a vector with all macro elements that have a given vertex DOF in common.
306
    vector<ElementObjectData>& getElements(DegreeOfFreedom vertex)
Thomas Witkowski's avatar
Thomas Witkowski committed
307
308
309
310
    {
      return vertexElements[vertex];
    }

311
    /// Returns a vector with all macro elements that have a given edge in common.
312
    vector<ElementObjectData>& getElements(DofEdge edge)
Thomas Witkowski's avatar
Thomas Witkowski committed
313
314
315
316
    {
      return edgeElements[edge];
    }

317
    /// Returns a vector with all macro elements that have a given face in common.
318
    vector<ElementObjectData>& getElements(DofFace face)
Thomas Witkowski's avatar
Thomas Witkowski committed
319
320
321
322
    {
      return faceElements[face];
    }

323
324
325
    
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given vertex DOF in common.
326
    map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex)
327
328
329
330
    {
      return vertexInRank[vertex];
    }

331
332
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given edge in common.
333
    map<int, ElementObjectData>& getElementsInRank(DofEdge edge)
334
335
336
337
    {
      return edgeInRank[edge];
    }

338
339
    /// Returns a map that maps to each rank all macro elements in this rank that
    /// have a given face in common.
340
    map<int, ElementObjectData>& getElementsInRank(DofFace face)
341
342
343
344
    {
      return faceInRank[face];
    }

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

350
351
352
      return vertexLocalMap[data];
    }

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

358
359
360
      return edgeLocalMap[data];
    }

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

366
367
368
      return faceLocalMap[data];
    }

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

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

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

384
    /// Write the element database to disk.
385
    void serialize(ostream &out);
386
387
    
    /// Read the element database from disk.
388
    void deserialize(istream &in);
389

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  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;
    }

424
425
426
427
    BoundaryType provideConnectedPeriodicBoundary(BoundaryType b0, 
						  BoundaryType b1);

    BoundaryType getNewBoundaryType();
428
429

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

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

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
441
  private:
442
443
444
445
446
447
448
449
    /// The used FE space.
    FiniteElemSpace *feSpace;

    /// The mesh that is used to store all its element information in the database.
    Mesh *mesh;


    /// Maps to each vertex DOF all element objects that represent this vertex.
450
    map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
451
452

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

455
456
    /// Maps to each face all element objects that represent this edge.
    map<DofFace, vector<ElementObjectData> > faceElements;
457

458
459
    
    /// Maps to an element object the corresponding vertex DOF.
460
    map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
461
462

    /// Maps to an element object the corresponding edge.
463
    map<ElementObjectData, DofEdge> edgeLocalMap;
464
465

    /// Maps to an element object the corresponding face.
466
    map<ElementObjectData, DofFace> faceLocalMap;
467
468


469
    /// Defines for all vertex DOFs the rank that ownes this vertex DOF.
470
    map<DegreeOfFreedom, int> vertexOwner;
471
472

    /// Defines for all edges the rank that ownes this edge.
473
    map<DofEdge, int> edgeOwner;
474
475

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

478

479
480
    /// Defines to each vertex DOF a map that maps to each rank number the element
    /// objects that have this vertex DOF in common.
481
    map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank;
482
483
484

    /// Defines to each edge a map that maps to each rank number the element objects
    /// that have this edge in common.
485
    map<DofEdge, map<int, ElementObjectData> > edgeInRank;
486
487
488

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

491
492

    /// Vertex iterator to iterate over \ref vertexInRank
493
    map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter;
494
495

    /// Edge iterator to iterate over \ref edgeInRank
496
    map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter;
497
498

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

501
502
503
504
505

    /// 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
506
    GeoIndex iterGeoPos;
507

508
509
    std::map<std::pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;

510
511
512
513
    // The following three data structures store periodic DOFs, edges and faces.
    PerBoundMap<DegreeOfFreedom>::type periodicVertices;
    PerBoundMap<DofEdge>::type periodicEdges;
    PerBoundMap<DofFace>::type periodicFaces;
514
515
516
517
518
519

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

    // Stores to each edge all its periodic associations.
    std::map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;
Thomas Witkowski's avatar
Thomas Witkowski committed
520
521
522
523
524
  };

}

#endif