InteriorBoundary.h 6.65 KB
Newer Older
1 2 3 4
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
5
// ==  http://www.amdis-fem.org                                              ==
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.


20 21 22 23 24 25 26

/** \file InteriorBoundary.h */

#ifndef AMDIS_INTERIORBOUNDARY_H
#define AMDIS_INTERIORBOUNDARY_H

#include <vector>
Thomas Witkowski's avatar
Thomas Witkowski committed
27
#include <map>
28

29
#include "AMDiS_fwd.h"
30 31
#include "MacroElement.h"
#include "Element.h"
32
#include "Boundary.h"
33
#include "parallel/MeshLevelData.h"
34 35 36

namespace AMDiS {

37 38 39
  using namespace std;

  typedef vector<pair<GeoIndex, int> > ExcludeList;
40

41 42
  /// Defines the geometrical objects that forms the boundary;
  struct BoundaryObject {
43

44 45 46 47 48 49 50
    BoundaryObject();

    BoundaryObject(Element *e, 
		   int eType, 
		   GeoIndex sObj, 
		   int iObj, 
		   bool rMode = false);
51

52 53
    static bool computeReverseMode(BoundaryObject &obj0,
				   BoundaryObject &obj1,
54
				   const FiniteElemSpace *feSpace,
55 56
				   BoundaryType boundary);

57 58 59 60
    bool operator==(const BoundaryObject& other) const;
    
    bool operator!=(const BoundaryObject& other) const;

61
    /// The macro element to which the boundary element corresponds to.
Thomas Witkowski's avatar
Thomas Witkowski committed
62
    Element* el;
63

64 65 66
    /// Index of the macro element.
    int elIndex;

67 68 69
    /// Element type index, only used in 3d.
    int elType;

70 71 72 73
    /** \brief
     * Defines the geometrical object at the boundary. It must be "a part" of the
     * macro element \ref el, i.e., either 1 (a vertex), 2 (an edge) or 3 (a face).
     */
74
    GeoIndex subObj;
75 76

    /** \brief
77
     * Defines which of vertex, edge or face of the macro element is part of the
78 79
     * boundary.
     *
80 81 82
     * Example: If the macro element is a triangle, than \ref subObj may be either
     * 1 (vertex) or 2 (edge). Assume its the last one. So this variable defines
     * which of the three possible edges of the triangle is at the interior
83 84
     * boundary.
     */
85
    int ithObj;
86 87 88

    bool reverseMode;

89
    /** \brief
90 91 92 93 94 95 96
     * In many situations it may be necessary to exclude some parts of the 
     * element to be part of the boundary. In 3d, when a face is part of the 
     * boundary, an edge or an vertex may be exludeded. In 2d only vertices may
     * be exluded to be part of an edge boundary. This list contains pairs of 
     * exludeded structures. The first component of every pair denotes if it is
     * a vertex or an edge, and the second component denotes the local index of
     * the structure.
97 98
     */
    ExcludeList excludedSubstructures;
99 100
  };

101 102


103 104 105 106 107
  /** \brief 
   * Defines one atomic part of the boundary, i.e., two boundary objects where the
   * boundary goes through.
   */
  struct AtomicBoundary {
108 109 110 111 112 113
    AtomicBoundary()
      : type(INTERIOR)
    {}

    bool operator==(const AtomicBoundary& other) const;

114
    /// The rank's part of the boundary.
115
    BoundaryObject rankObj;
116 117

    /// The object on the other side of the boundary.
118
    BoundaryObject neighObj;
119 120 121 122 123

    /// Integer flag that is used to distinguish between different types of 
    /// boundaries. Till now it is used only for periodic boundaries, which are also
    /// handles as interior boundaries.
    BoundaryType type;
124 125
  };

126 127


128 129 130 131 132
  /** \brief
   * Defines the interior boundary, i.e. a bound within the domain. It is used for
   * the classical domain decomposition parallelization.
   */
  class InteriorBoundary {
Thomas Witkowski's avatar
Thomas Witkowski committed
133
  public:
134
    typedef map<int, vector<AtomicBoundary> > RankToBoundMap;
Thomas Witkowski's avatar
Thomas Witkowski committed
135

Thomas Witkowski's avatar
Thomas Witkowski committed
136 137 138 139
    /// Iterator for the interior boundary object.
    class iterator {      
    public:
      iterator(InteriorBoundary &b)
140 141 142 143 144 145 146 147 148 149 150
	: bound(b),
	  levelData(NULL),
	  level(0)
      {
	reset();
      }

      iterator(InteriorBoundary &b, MeshLevelData &levelData, int level)
	: bound(b),
	  levelData(&levelData),
	  level(level)
Thomas Witkowski's avatar
Thomas Witkowski committed
151 152 153 154 155 156 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
      {
	reset();
      }

      /// Set the iterator to the first position.
      void reset()
      {
	mapIt = bound.boundary.begin();
	nextNonempty();

	if (mapIt != bound.boundary.end())
	  vecIt = mapIt->second.begin();	
      }

      /// Test if iterator is at the final position.
      bool end() const
      {
	return (mapIt == bound.boundary.end());
      }

      /// Move iterator to the next position.
      void operator++()
      {
	++vecIt;
	if (vecIt == mapIt->second.end()) {
	  ++mapIt;
	  nextNonempty();

	  if (mapIt != bound.boundary.end())
	    vecIt = mapIt->second.begin();	  
	}	
      }

184 185 186 187 188 189 190 191 192 193
      inline AtomicBoundary& operator*()
      {
	return *vecIt;
      }

      inline AtomicBoundary* operator->()
      {
	return &(*vecIt);
      }

Thomas Witkowski's avatar
Thomas Witkowski committed
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
      void nextRank()
      {
	++mapIt;
	nextNonempty();

	if (mapIt != bound.boundary.end())
	  vecIt = mapIt->second.begin();	
      }

      int getRank() 
      {
	return mapIt->first;
      }

    protected:

      inline void nextNonempty()
      {
Thomas Witkowski's avatar
Thomas Witkowski committed
212 213 214
	if (mapIt == bound.boundary.end())
	  return;

215 216 217 218
	if (level > 0) {
	  TEST_EXIT_DBG(levelData)("No mesh level data object defined!\n");
	  TEST_EXIT_DBG(level == 1)("Only 2-level method supported!\n");

219 220 221 222 223 224 225 226 227 228 229 230
	  while (levelData->rankInSubdomain(mapIt->first, level) ||
		 mapIt->second.size() == 0) {
	    ++mapIt;
	    if (mapIt == bound.boundary.end())
	      return;	  
	  }
	} else {
	  while (mapIt->second.size() == 0) {
	    ++mapIt;
	    if (mapIt == bound.boundary.end())
	      return;
	  }
Thomas Witkowski's avatar
Thomas Witkowski committed
231 232 233 234 235 236
	}
      }

    protected:
      RankToBoundMap::iterator mapIt;

237
      vector<AtomicBoundary>::iterator vecIt;
Thomas Witkowski's avatar
Thomas Witkowski committed
238 239

      InteriorBoundary &bound;
240 241 242 243

      MeshLevelData *levelData;

      int level;
Thomas Witkowski's avatar
Thomas Witkowski committed
244 245
    };

246
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
247 248
    InteriorBoundary() {}

Thomas Witkowski's avatar
Thomas Witkowski committed
249 250 251 252 253
    void clear()
    {
      boundary.clear();
    }

254
    AtomicBoundary& getNewAtomic(int rank);
Thomas Witkowski's avatar
Thomas Witkowski committed
255

256
    /// Writes this object to a file.
257
    void serialize(ostream &out);
258

259
    /// Reads the state of an interior boundary from a file.
260
    void deserialize(istream &in, map<int, Element*> &elIndexMap);
261

262 263 264 265
    /// Compares this interior boundaries with some other. The order of the
    /// boundary elements within the object does not play a role.
    bool operator==(const InteriorBoundary& other) const;

266
  protected:
267
    void serializeExcludeList(ostream &out, ExcludeList &list);
268

269
    void deserializeExcludeList(istream &in, ExcludeList &list);
270

Thomas Witkowski's avatar
Thomas Witkowski committed
271
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
272
    RankToBoundMap boundary;
273 274 275 276
  };
}

#endif // AMDIS_INTERIORBOUNDARY_H