DofComm.h 6.05 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ==  http://www.amdis-fem.org                                              ==
// ==                                                                        ==
// ============================================================================
//
// 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.



/** \file DofComm.h */

#ifndef AMDIS_DOF_COMM_H
#define AMDIS_DOF_COMM_H

26
#include <mpi.h>
27
#include <map>
28
#include "parallel/ParallelTypes.h"
29
30
31
32
33
34
35
36
37
38
#include "FiniteElemSpace.h"
#include "Global.h"

namespace AMDiS {

  using namespace std;

  class DofComm
  {
  public:
39
    DofComm() 
40
41
      : recvDofs(1),
	sendDofs(1),
42
43
44
45
	periodicDofs(0),
	meshLevel(-1),
	nLevel(0),
	levelData(NULL)
46
    {}
47
48
49
    
    typedef map<const FiniteElemSpace*, DofContainer> FeMapType;
    typedef FeMapType::iterator FeMapIter;
50
    typedef map<int, FeMapType> DataType;
51
    typedef DataType::iterator DataIter;
52
53
    // meshLevel: map[rank -> map[feSpace -> DofContainer]]
    typedef vector<DataType> LevelDataType;
54

55
56
57
    void init(int level, 
	      MeshLevelData &levelData, 
	      vector<const FiniteElemSpace*> &fe);
58
59
60
61
62
63
64
65
66
67
68

    void create(InteriorBoundary &boundary);

    LevelDataType& getSendDofs()
    {
      return sendDofs;
    }

    LevelDataType& getRecvDofs()
    {
      return recvDofs;
69
70
    }

71
    LevelDataType& getPeriodicDofs()
72
    {
73
      return periodicDofs;
74
75
    }

76
    // Writes all data of this object to an output stream.
Thomas Witkowski's avatar
Thomas Witkowski committed
77
    void serialize(ostream &out);
78

79
80
    // Reads the object data from an input stream.
    void deserialize(istream &in, 
Thomas Witkowski's avatar
Thomas Witkowski committed
81
		     map<const FiniteElemSpace*, map<int, const DegreeOfFreedom*> > dofIndexMap);
82
83
84

    int getNumberDofs(LevelDataType &data, 
		      int level, 
Thomas Witkowski's avatar
Blub    
Thomas Witkowski committed
85
86
		      const FiniteElemSpace *feSpace,
		      bool countDouble = false);
87
88
89

  protected:
    void createContainer(RankToBoundMap &boundary, LevelDataType &data);
90

Thomas Witkowski's avatar
Thomas Witkowski committed
91
92
93
94
95
96
    void serialize(LevelDataType &data, ostream &out);

    void deserialize(LevelDataType &data,
		     istream &in, 
		     map<const FiniteElemSpace*, map<int, const DegreeOfFreedom*> > dofIndexMap);

97
  protected:
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    /// This map contains for each rank the list of DOFs the current rank must 
    /// end to exchange solution DOFs at the interior boundaries.
    LevelDataType sendDofs;

    /// This map contains on each rank the list of DOFs from which the current 
    /// rank will receive DOF values (i.e., this are all DOFs at an interior 
    /// boundary). The DOF indices are given in rank's local numbering.
    LevelDataType recvDofs;

    /// This map contains on each rank a list of DOFs along the interior bound-
    /// aries to communicate with other ranks. The DOF indices are given in rank's
    /// local numbering. Periodic boundaries within one subdomain are not 
    /// considered here. 
    LevelDataType periodicDofs;
112

113
114
    int meshLevel;

115
116
    int nLevel;

117
118
    MeshLevelData *levelData;

119
120
    vector<const FiniteElemSpace*> feSpaces;

121
122
123
124
125
126
    friend class Iterator;

  public:
    class Iterator
    {
    public:
127
      Iterator(LevelDataType &d,
128
	       const FiniteElemSpace *fe = NULL)
129
	: data(d),
130
	  dofCounter(-1),
131
	  traverseFeSpace(fe),
132
133
	  traverseLevel(0),
	  removedDof(false)
134
      {
135
136
	goFirst();
      }
137

138
      Iterator(LevelDataType &d,
139
140
	       int level,
	       const FiniteElemSpace *fe = NULL)
141
	: data(d),
142
143
	  dofCounter(-1),
	  traverseFeSpace(fe),
144
145
	  traverseLevel(level),
	  removedDof(false)
146
147
      {
	goFirst();
148
149
150
151
      }

      inline bool end()
      {
152
	return (dataIter == data[traverseLevel].end());
153
154
155
156
      }
      
      inline void nextRank()
      {
157
158
159
	do {
	  ++dataIter;
	} while (setNextFeMap() == false);
160
161
162
163
164
165
166
      }

      inline void nextFeSpace()
      {
	++feMapIter;
      }

167
168
169
170
      inline void next()
      {
	++feMapIter;
	if (feMapIter == dataIter->second.end()) {
171
172
173
	  do {
	    ++dataIter;
	  } while (setNextFeMap() == false);
174
175
176
177
178
179
	} else {
	  dofIter = feMapIter->second.begin();
	  dofCounter = 0;
	}
      }

180
181
182
183
184
185
186
187
188
189
190
191
      inline void beginDofIter(const FiniteElemSpace *fe = NULL)
      {
	FUNCNAME("DofComm::Iterator::beginDofIter()");

	if (fe != NULL) {
	  feMapIter = dataIter->second.begin();

	  while (feMapIter->first != fe &&
		 feMapIter != dataIter->second.end())
	    ++feMapIter;
	}

192
193
194
195
	if (feMapIter != dataIter->second.end()) {
	  dofIter = feMapIter->second.begin();
	  dofCounter = 0;
	}
196
197
198
199
      }

      inline bool endDofIter()
      {
200
201
202
	if (feMapIter == dataIter->second.end())
	  return true;

203
204
205
206
207
	return (dofIter == feMapIter->second.end());
      }
      
      inline void nextDof()
      {
208
209
210
211
212
213
214
215
216
217
218
219
	if (removedDof) {
	  removedDof = false;
	} else {
	  ++dofIter;
	  ++dofCounter;
	}
      }

      inline void removeDof()
      {
	dofIter = feMapIter->second.erase(dofIter);
	removedDof = true;
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
      }

      inline int getRank()
      {
	return dataIter->first;
      }

      inline const FiniteElemSpace* getFeSpace()
      {
	return feMapIter->first;
      }

      inline DofContainer& getDofs()
      {
	return feMapIter->second;
      }

      inline const DegreeOfFreedom* getDof()
      {
	return *dofIter;
      }

      inline DegreeOfFreedom getDofIndex()
      {
	return **dofIter;
      }

      inline int getDofCounter()
      {
	return dofCounter;
      }

    protected:
253
254
      void goFirst()
      {
255
	dataIter = data[traverseLevel].begin();
256
257
258
259
260

	while (setNextFeMap() == false)
	  ++dataIter;
      }

261
      bool setNextFeMap();
262
263

    protected:
264
      LevelDataType &data;
265
266
267
268
269
270
271
272
273
274
      
      DofComm::DataIter dataIter;
      
      DofComm::FeMapIter feMapIter;

      DofContainer::iterator dofIter;

      int dofCounter;

      const FiniteElemSpace *traverseFeSpace;
275
276

      int traverseLevel;
277
278

      bool removedDof;
279
280
281
282
283
284
285
286
    };


  };

}

#endif // AMDIS_DOF_COMM_H