ElementObjectData.h 17.3 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
      : mesh(NULL),
105
	iterGeoPos(CENTER)
Thomas Witkowski's avatar
Thomas Witkowski committed
106 107
    {}

108

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


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


    /** \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.
     */
146
    void createRankData(map<int, int>& macroElementRankMap);
Thomas Witkowski's avatar
Thomas Witkowski committed
147

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

163

164 165 166 167 168 169 170 171
    /** \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
172 173
    bool iterate(GeoIndex pos)
    {
174 175 176
      // 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
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 223 224 225 226 227 228 229 230 231 232 233 234
      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;
    }


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


257
    /// Returns the rank owner of the current iterator position.
Thomas Witkowski's avatar
Thomas Witkowski committed
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
    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;
      }
    }

278

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

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

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

297

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

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

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


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

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

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

335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360

    /// Returns a vector with all macro elements that have a given vertex DOF in common.
    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];
    }


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

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

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

383
    /// Returns to an element object data the appropriate vertex DOF.
384 385
    DegreeOfFreedom getVertexLocalMap(ElementObjectData &data)
    {
386 387
      TEST_EXIT_DBG(vertexLocalMap.count(data))("Should not happen!\n");

388 389 390
      return vertexLocalMap[data];
    }

391
    /// Returns to an element object data the appropriate edge.
392 393
    DofEdge getEdgeLocalMap(ElementObjectData &data)
    {
394 395
      TEST_EXIT_DBG(edgeLocalMap.count(data))("Should not happen!\n");

396 397 398
      return edgeLocalMap[data];
    }

399
    /// Returns to an element object data the appropriate face.
400 401
    DofFace getFaceLocalMap(ElementObjectData &data)
    {
402 403
      TEST_EXIT_DBG(faceLocalMap.count(data))("Should not happen!\n");

404 405 406
      return faceLocalMap[data];
    }

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
    PerBoundMap<DegreeOfFreedom>::type& getPeriodicVertices()
    {
      return periodicVertices;
    }

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

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

422
    inline bool getEdgeReverseMode(ElementObjectData &obj0, ElementObjectData &obj1)
423
    {
424 425 426
      if (mesh->getDim() == 2)
	return true;

427 428 429 430 431 432
      TEST_EXIT_DBG(edgeReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

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

433
    inline bool getFaceReverseMode(ElementObjectData &obj0, ElementObjectData &obj1)
434 435 436 437 438 439 440
    {
      TEST_EXIT_DBG(faceReverseMode.count(make_pair(obj0, obj1)))
	("Should not happen!\n");

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

441 442 443 444 445 446
    /// Returns true if there is periodic data.
    bool hasPeriodicData()
    {
      return (periodicVertices.size() != 0);
    }

447
    /// Write the element database to disk.
448
    void serialize(ostream &out);
449 450
    
    /// Read the element database from disk.
451
    void deserialize(istream &in);
452

453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
  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;
    }

487
    BoundaryType getNewBoundaryType(DOFAdmin *admin);
488

489 490 491
    BoundaryType provideConnectedPeriodicBoundary(DOFAdmin *admin,
						  BoundaryType b0, 
						  BoundaryType b1);
492 493

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

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

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
505
  private:
506 507 508 509
    /// 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.
510
    map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
511 512

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

515 516
    /// Maps to each face all element objects that represent this edge.
    map<DofFace, vector<ElementObjectData> > faceElements;
517

518 519
    
    /// Maps to an element object the corresponding vertex DOF.
520
    map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
521 522

    /// Maps to an element object the corresponding edge.
523
    map<ElementObjectData, DofEdge> edgeLocalMap;
524 525

    /// Maps to an element object the corresponding face.
526
    map<ElementObjectData, DofFace> faceLocalMap;
527 528


529
    /// Defines for all vertex DOFs the rank that ownes this vertex DOF.
530
    map<DegreeOfFreedom, int> vertexOwner;
531 532

    /// Defines for all edges the rank that ownes this edge.
533
    map<DofEdge, int> edgeOwner;
534 535

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

538

539 540
    /// Defines to each vertex DOF a map that maps to each rank number the element
    /// objects that have this vertex DOF in common.
541
    map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank;
542 543 544

    /// Defines to each edge a map that maps to each rank number the element objects
    /// that have this edge in common.
545
    map<DofEdge, map<int, ElementObjectData> > edgeInRank;
546 547 548

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

551 552

    /// Vertex iterator to iterate over \ref vertexInRank
553
    map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter;
554 555

    /// Edge iterator to iterate over \ref edgeInRank
556
    map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter;
557 558

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

561 562 563 564 565

    /// 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
566
    GeoIndex iterGeoPos;
567

568
    map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
569

570 571 572 573
    // The following three data structures store periodic DOFs, edges and faces.
    PerBoundMap<DegreeOfFreedom>::type periodicVertices;
    PerBoundMap<DofEdge>::type periodicEdges;
    PerBoundMap<DofFace>::type periodicFaces;
574 575

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

    // Stores to each edge all its periodic associations.
579 580 581 582 583
    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
584 585 586 587 588
  };

}

#endif