DofComm.h 5.33 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
42
43
    
    typedef map<const FiniteElemSpace*, DofContainer> FeMapType;
    typedef FeMapType::iterator FeMapIter;
44
    typedef map<int, FeMapType> DataType;
45
46
    typedef DataType::iterator DataIter;

47
    void init(vector<const FiniteElemSpace*> &fe);
48
49
50

    void create(InteriorBoundary &boundary);

51
    DataType& getSendDofs()
52
53
54
55
    {
      return sendDofs;
    }

56
    DataType& getRecvDofs()
57
58
    {
      return recvDofs;
59
60
    }

61
    DataType& getPeriodicDofs()
62
    {
63
      return periodicDofs;
64
65
    }

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

69
    int getNumberDofs(DataType &data, 
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
70
71
		      const FiniteElemSpace *feSpace,
		      bool countDouble = false);
72
73

  protected:
74
75
    void createContainer(RankToBoundMap &boundary, 
			 DataType &data);
76

77
  protected:
78
79
    /// This map contains for each rank the list of DOFs the current rank must 
    /// end to exchange solution DOFs at the interior boundaries.
80
    DataType sendDofs;
81
82
83
84

    /// 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.
85
    DataType recvDofs;
86
87
88
89
90

    /// 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. 
91
    DataType periodicDofs;
92

93
94
    vector<const FiniteElemSpace*> feSpaces;

95
96
97
98
99
100
    friend class Iterator;

  public:
    class Iterator
    {
    public:
101
      Iterator(DataType &d,
102
	       const FiniteElemSpace *fe = NULL)
103
	: data(d),
104
105
	  dofCounter(-1),
	  traverseFeSpace(fe),
106
	  removedDof(false)
107
108
      {
	goFirst();
109
110
111
112
      }

      inline bool end()
      {
113
	return (dataIter == data.end());
114
115
116
117
      }
      
      inline void nextRank()
      {
118
119
120
	do {
	  ++dataIter;
	} while (setNextFeMap() == false);
121
122
123
124
125
126
127
      }

      inline void nextFeSpace()
      {
	++feMapIter;
      }

128
129
130
131
      inline void next()
      {
	++feMapIter;
	if (feMapIter == dataIter->second.end()) {
132
133
134
	  do {
	    ++dataIter;
	  } while (setNextFeMap() == false);
135
136
137
138
139
140
	} else {
	  dofIter = feMapIter->second.begin();
	  dofCounter = 0;
	}
      }

141
142
143
144
145
146
147
148
149
150
151
152
      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;
	}

153
154
155
156
	if (feMapIter != dataIter->second.end()) {
	  dofIter = feMapIter->second.begin();
	  dofCounter = 0;
	}
157
158
159
160
      }

      inline bool endDofIter()
      {
161
162
163
	if (feMapIter == dataIter->second.end())
	  return true;

164
165
166
167
168
	return (dofIter == feMapIter->second.end());
      }
      
      inline void nextDof()
      {
169
170
171
172
173
174
175
176
177
178
179
180
	if (removedDof) {
	  removedDof = false;
	} else {
	  ++dofIter;
	  ++dofCounter;
	}
      }

      inline void removeDof()
      {
	dofIter = feMapIter->second.erase(dofIter);
	removedDof = true;
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
      }

      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:
214
215
      void goFirst()
      {
216
	dataIter = data.begin();
217
218
219
220
221

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

222
      bool setNextFeMap();
223
224

    protected:
225
      DataType &data;
226
227
228
229
230
231
232
233
234
235
      
      DofComm::DataIter dataIter;
      
      DofComm::FeMapIter feMapIter;

      DofContainer::iterator dofIter;

      int dofCounter;

      const FiniteElemSpace *traverseFeSpace;
236

237
      bool removedDof;
238
239
    };

240
241
242
243
244
245
246
247
248
249
250
251
252
253
  };

  
  class MultiLevelDofComm {
  public:
    void init(MeshLevelData &levelData,
	      vector<const FiniteElemSpace*> &fe);

    void create(MultiLevelInteriorBoundary &boundary);

    inline DofComm& operator[](int level) 
    {
      return levelDofComm[level];
    }
254

255
256
  private:
    map<int, DofComm> levelDofComm;
257
258
259
260
261
  };

}

#endif // AMDIS_DOF_COMM_H