DofComm.h 5.45 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
 * Authors: 
 * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *
 * This file is part of AMDiS
 *
 * See also license.opensource.txt in the distribution.
 * 
 ******************************************************************************/
20
21
22
23
24
25
26
27



/** \file DofComm.h */

#ifndef AMDIS_DOF_COMM_H
#define AMDIS_DOF_COMM_H

28
#include <mpi.h>
29
#include <map>
30
#include "parallel/ParallelTypes.h"
31
32
33
#include "FiniteElemSpace.h"
#include "Global.h"

34
namespace AMDiS { namespace Parallel {
35
36
37
38

  class DofComm
  {
  public:
39
    DofComm() 
40
      {}
41
    
42
    typedef std::map<const FiniteElemSpace*, DofContainer> FeMapType;
43
    typedef FeMapType::iterator FeMapIter;
44
    typedef std::map<int, FeMapType> DataType;
45
46
    typedef DataType::iterator DataIter;

47
    void init(std::vector<const FiniteElemSpace*> &fe);
48

49
50
51
52
53
54
    void create(Mesh* mesh, InteriorBoundary &boundary);

    Mesh* getMesh()
    {
      return mesh;
    }
55

56
    DataType& getSendDofs()
57
58
59
60
    {
      return sendDofs;
    }

61
    DataType& getRecvDofs()
62
63
    {
      return recvDofs;
64
65
    }

66
    DataType& getPeriodicDofs()
67
    {
68
      return periodicDofs;
69
70
    }

71
    // Writes all data of this object to an output stream.
72
    void serialize(std::ostream &out);
73

74
    int getNumberDofs(DataType &data, 
Thomas Witkowski's avatar
Blub    
Thomas Witkowski committed
75
76
		      const FiniteElemSpace *feSpace,
		      bool countDouble = false);
77

78
79
80
    int getDegree(const FiniteElemSpace *feSpace, 
		  const DegreeOfFreedom *dof);

81
  protected:
82
83
84
    void createContainer(Mesh* mesh,
			 InteriorBoundary& boundary,
                         RankToBoundMap& rankToBoundMap, 
85
			 DataType &data);
86

87
  protected:
88
    /// This map contains for each rank the list of DOFs the current rank must 
89
    /// send to exchange solution DOFs at the interior boundaries.
90
    DataType sendDofs;
91
92
93
94

    /// 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.
95
    DataType recvDofs;
96
97
98
99
100

    /// 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. 
101
    DataType periodicDofs;
102

103
    std::vector<const FiniteElemSpace*> feSpaces;
104

105
106
    Mesh* mesh;

107
108
109
110
111
112
    friend class Iterator;

  public:
    class Iterator
    {
    public:
113
      Iterator(DataType &d,
114
	       const FiniteElemSpace *fe = NULL)
115
	: data(d),
116
117
	  dofCounter(-1),
	  traverseFeSpace(fe),
118
	  removedDof(false)
119
120
      {
	goFirst();
121
122
123
124
      }

      inline bool end()
      {
125
	return (dataIter == data.end());
126
127
128
129
      }
      
      inline void nextRank()
      {
130
131
132
	do {
	  ++dataIter;
	} while (setNextFeMap() == false);
133
134
135
136
137
138
139
      }

      inline void nextFeSpace()
      {
	++feMapIter;
      }

140
141
142
143
      inline void next()
      {
	++feMapIter;
	if (feMapIter == dataIter->second.end()) {
144
145
146
	  do {
	    ++dataIter;
	  } while (setNextFeMap() == false);
147
148
149
150
151
152
	} else {
	  dofIter = feMapIter->second.begin();
	  dofCounter = 0;
	}
      }

153
      inline void beginDofIter(const FiniteElemSpace *fe = NULL)
154
      {
155
	if (fe != NULL) {
156
157
158
159
160
161
162
	  feMapIter = dataIter->second.begin();

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

163
164
165
166
	if (feMapIter != dataIter->second.end()) {
	  dofIter = feMapIter->second.begin();
	  dofCounter = 0;
	}
167
168
169
170
      }

      inline bool endDofIter()
      {
171
172
173
	if (feMapIter == dataIter->second.end())
	  return true;

174
175
176
177
178
	return (dofIter == feMapIter->second.end());
      }
      
      inline void nextDof()
      {
179
180
181
182
183
184
185
186
187
188
189
190
	if (removedDof) {
	  removedDof = false;
	} else {
	  ++dofIter;
	  ++dofCounter;
	}
      }

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

      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:
224
225
      void goFirst()
      {
226
	dataIter = data.begin();
227
228
229
230
231

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

232
      bool setNextFeMap();
233
234

    protected:
235
      DataType &data;
236
237
238
239
240
241
242
243
244
245
      
      DofComm::DataIter dataIter;
      
      DofComm::FeMapIter feMapIter;

      DofContainer::iterator dofIter;

      int dofCounter;

      const FiniteElemSpace *traverseFeSpace;
246

247
      bool removedDof;
248
249
    };

250
251
252
253
254
  };

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

258
259
     void create(Mesh* mesh, MultiLevelInteriorBoundary &boundary);
    
260
261
262
263
264

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

266
  private:
267
    std::map<int, DofComm> levelDofComm;
268
269
  };

270
} }
271
272

#endif // AMDIS_DOF_COMM_H