InteriorBoundary.h 5.45 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
#include "BoundaryObject.h"
31
#include "parallel/ParallelTypes.h"
32
33
34

namespace AMDiS {

35
36
  using namespace std;

37
38
39
40
41
  /** \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
42
  public:
43
44
    void create(MeshLevelData &levelData,
		int level,
45
		ElementObjectDatabase &elObjDb);
Thomas Witkowski's avatar
Thomas Witkowski committed
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    RankToBoundMap& getOwn()
    {
      return own;
    }
 
    RankToBoundMap& getOther()
    {
      return other;
    }

    RankToBoundMap& getPeriodic()
    {
      return periodic;
    }

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    vector<AtomicBoundary>& getOwn(int rank)
    {
      return own[rank];
    }
 
    vector<AtomicBoundary>& getOther(int rank)
    {
      return other[rank];
    }

    vector<AtomicBoundary>& getPeriodic(int rank)
    {
      return periodic[rank];
    }

77
78
79
80
81
    bool hasPeriodic()
    {
      return static_cast<bool>(periodic.size());
    }

82
83
84
85
86
87
    /// Writes this object to a file.
    void serialize(ostream &out);

    /// Reads the state of an interior boundary from a file.
    void deserialize(istream &in, Mesh *mesh);

88
  private:
89
90
91
92
93
94
95
    /// In this function, we put some verification procedures to check for 
    /// consistency if the created interior boundary data. This function is
    /// enabled even for optimized mode to check all possible meshes. Thus,
    /// everything herein should be fast. If the code is stable, we can think
    /// to remove this function.
    void verifyBoundary();

96
97
98
99
100
101
    AtomicBoundary& getNewOwn(int rank);

    AtomicBoundary& getNewOther(int rank);

    AtomicBoundary& getNewPeriodic(int rank);

102
103
104
105
106
107
108
109
110
111
112
113
114
    /// Checks whether the given boundary is already a other boundary with 
    /// given rank number. Returns true, if the bound is already in the other
    /// boundary database.
    bool checkOther(AtomicBoundary& bound, int rank);

    /// Removes the given boundary object from all owned boundaries. Returns 
    /// true, if at least one object has been removed, otherwise false.
    bool removeOwn(BoundaryObject& bound);

    /// Removes the given boundary object from all other boundaries. Returns 
    /// true, if at least one object has been removed, otherwise false.
    bool removeOther(BoundaryObject& bound);

115
116
117
118
119
120
    void serialize(ostream &out, RankToBoundMap& boundary);

    void deserialize(istream &in, 
		     RankToBoundMap& boundary,
		     map<int, Element*> &elIndexMap);

121
122
123
124
    void serializeExcludeList(ostream &out, ExcludeList &list);

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

125
  private:
126
127
    RankToBoundMap own, other, periodic;

128
    friend class ParallelDebug;
129
130

  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
131
132
133
    /// Iterator for the interior boundary object.
    class iterator {      
    public:
134
      iterator(RankToBoundMap &b, int traverseLevel = 0)
135
	: bound(b),
136
	  level(traverseLevel)
137
138
139
140
      {
	reset();
      }

Thomas Witkowski's avatar
Thomas Witkowski committed
141
142
143
      /// Set the iterator to the first position.
      void reset()
      {
144
	mapIt = bound.begin();
Thomas Witkowski's avatar
Thomas Witkowski committed
145
146
147
148
149
150
	nextNonempty();
      }

      /// Test if iterator is at the final position.
      bool end() const
      {
151
	return (mapIt == bound.end());
Thomas Witkowski's avatar
Thomas Witkowski committed
152
153
154
155
156
      }

      /// Move iterator to the next position.
      void operator++()
      {
157
158
	do {
	  ++vecIt;
159
	} while (vecIt != mapIt->second.end() && vecIt->maxLevel < level);
160

Thomas Witkowski's avatar
Thomas Witkowski committed
161
162
163
164
165
166
	if (vecIt == mapIt->second.end()) {
	  ++mapIt;
	  nextNonempty();
	}	
      }

167
168
169
170
171
172
173
174
175
176
      inline AtomicBoundary& operator*()
      {
	return *vecIt;
      }

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

Thomas Witkowski's avatar
Thomas Witkowski committed
177
178
179
180
181
182
      void nextRank()
      {
	++mapIt;
	nextNonempty();
      }

183
      inline int getRank() 
Thomas Witkowski's avatar
Thomas Witkowski committed
184
185
186
187
188
189
190
191
      {
	return mapIt->first;
      }

    protected:

      inline void nextNonempty()
      {
192
193
	do {
	  // Return, we are at the end.
194
	  if (mapIt == bound.end())
195
196
197
198
199
	    return;
	  
	  // Search for the next non empty boundary map.
	  while (mapIt->second.size() == 0) {
	    ++mapIt;
200
	    if (mapIt == bound.end())
201
202
203
204
205
206
	      return;	  
	  }
	  
	  vecIt = mapIt->second.begin();
	  
	  // Search for the next atomic boundary on the mesh level
207
	  while (vecIt != mapIt->second.end() && vecIt->maxLevel < level)
208
209
210
211
212
213
214
215
216
	    ++vecIt;
	  
	  // If vector iterator is not at the end, we have found one and
	  // can return.
	  if (vecIt != mapIt->second.end())
	    return;
	  
	  // In this case, no boundary on the given level is found, continue
	  // with next rank.
217
	  ++mapIt;
218
	} while (true);
Thomas Witkowski's avatar
Thomas Witkowski committed
219
220
221
222
223
      }

    protected:
      RankToBoundMap::iterator mapIt;

224
      vector<AtomicBoundary>::iterator vecIt;
Thomas Witkowski's avatar
Thomas Witkowski committed
225

226
      RankToBoundMap &bound;
227

228
      int level;     
Thomas Witkowski's avatar
Thomas Witkowski committed
229
    };
230
231
232
233
  };
}

#endif // AMDIS_INTERIORBOUNDARY_H