FeSpaceMapping.h 7.04 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
// ============================================================================
// ==                                                                        ==
// == 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 FeSpaceMapping.h */

23
#include <vector>
24
#include <map>
Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
25
26
#include <set>
#include "parallel/DofComm.h"
27
28
29
30
31
32
33
34
35
#include "parallel/MpiHelper.h"
#include "parallel/ParallelTypes.h"

#ifndef AMDIS_FE_SPACE_MAPPING_H
#define AMDIS_FE_SPACE_MAPPING_H

namespace AMDiS {
  using namespace std;

Thomas Witkowski's avatar
Thomas Witkowski committed
36
37
38
39
40
  struct MultiIndex
  {
    int local, global;
  };

41
42
43
  class GlobalDofMap
  {
  public:
44
45
46
47
48
49
50
    /// This constructor exists only to create std::map of this class and make
    /// use of the operator [] for read access. Should never be called.
    GlobalDofMap() 
    {
      ERROR_EXIT("Should not be called!\n");
    }
      
51
52
    GlobalDofMap(MPI::Intracomm* m)
      : mpiComm(m),
Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
53
	feSpace(NULL),
Thomas Witkowski's avatar
Thomas Witkowski committed
54
55
	sendDofs(NULL),
	recvDofs(NULL),
Thomas Witkowski's avatar
Thomas Witkowski committed
56
	needGlobalMapping(false),
57
58
	nRankDofs(0),
	nOverallDofs(0),
Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
59
60
	rStartDofs(0),
	overlap(false)
61
62
    {}
    
63
    void clear();
64
    
Thomas Witkowski's avatar
Thomas Witkowski committed
65
    MultiIndex& operator[](DegreeOfFreedom d)
66
67
68
69
70
71
    {
      TEST_EXIT_DBG(dofMap.count(d))("Should not happen!\n");

      return dofMap[d];
    }
    
Thomas Witkowski's avatar
Thomas Witkowski committed
72
    void insertRankDof(DegreeOfFreedom dof0, DegreeOfFreedom dof1 = -1)
73
74
75
76
77
    {
      FUNCNAME("GlobalDofMap::insertRankDof()");
      
      TEST_EXIT_DBG(dofMap.count(dof0) == 0)("Should not happen!\n");
      
Thomas Witkowski's avatar
Thomas Witkowski committed
78
79
80
81
      dofMap[dof0].local = dof1;
      
      if (dof1 != -1)
	nRankDofs++;
82
83
    }
    
Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
84
    void insert(DegreeOfFreedom dof0, DegreeOfFreedom dof1 = -1)
85
86
87
88
89
    {
      FUNCNAME("GlobalDofMap::insert()");
      
      TEST_EXIT_DBG(dofMap.count(dof0) == 0)("Should not happen!\n");
      
Thomas Witkowski's avatar
Thomas Witkowski committed
90
      dofMap[dof0].local = dof1;
Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
91
92

      nonRankDofs.insert(dof0);
93
94
95
96
97
98
99
100
101
102
103
104
    }
    
    bool isSet(DegreeOfFreedom dof)
    {
      return static_cast<bool>(dofMap.count(dof));
    }
    
    unsigned int size()
    {
      return dofMap.size();
    }
    
Thomas Witkowski's avatar
Thomas Witkowski committed
105
    map<DegreeOfFreedom, MultiIndex>& getMap()
106
107
108
109
    {
      return dofMap;
    }
    
Thomas Witkowski's avatar
Thomas Witkowski committed
110
    void update();
111

112
    void addOffset(int offset);
113

Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
114
115
    void computeNonLocalIndices();

Thomas Witkowski's avatar
Thomas Witkowski committed
116
117
    void computeMatIndex(int offset);

Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
    void print();

    void setFeSpace(const FiniteElemSpace *fe)
    {
      feSpace = fe;
    }

    void setOverlap(bool b)
    {
      overlap = b;
    }

    void setDofComm(DofComm &pSend, DofComm &pRecv)
    {
      sendDofs = &pSend;
      recvDofs = &pRecv;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
136
137
138
139
140
    void setNeedGlobalMapping(bool b)
    {
      needGlobalMapping = b;
    }

141
142
  private:
    MPI::Intracomm* mpiComm;
Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
143
144
145

    const FiniteElemSpace *feSpace;

146
    /// 
Thomas Witkowski's avatar
Thomas Witkowski committed
147
    map<DegreeOfFreedom, MultiIndex> dofMap;
148

Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
149
150
151
152
153
    std::set<DegreeOfFreedom> nonRankDofs;

    DofComm *sendDofs;
    
    DofComm *recvDofs;
Thomas Witkowski's avatar
Thomas Witkowski committed
154
155

    bool needGlobalMapping;
156
157
158
  public:
    /// 
    int nRankDofs, nOverallDofs, rStartDofs;   
Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
159
160

    bool overlap;
161
162
163
164
165
166
167
  };
  

  template<typename T>
  class FeSpaceData
  {
  public:
168
169
170
171
172
173
174
    FeSpaceData() 
      : mpiComm(NULL),
	feSpaces(0),
	nRankDofs(-1),
	nOverallDofs(-1),
	rStartDofs(-1)
    {} 
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

    T& operator[](const FiniteElemSpace* feSpace)
    {
      FUNCNAME("FeSpaceData::operator[]()");

      TEST_EXIT_DBG(data.count(feSpace))("Should not happen!\n");

      return data.find(feSpace)->second;
    }

    void addFeSpace(const FiniteElemSpace* feSpace)
    {
      FUNCNAME("FeSpaceData::addFeSpace()");
      
      if (data.count(feSpace))
	data.find(feSpace)->second.clear();
      else
	data.insert(make_pair(feSpace, T(mpiComm)));
Thomas Witkowski's avatar
FETI-DP    
Thomas Witkowski committed
193
194

      data.find(feSpace)->second.setFeSpace(feSpace);
195
196
    }    

197
    int getRankDofs(vector<const FiniteElemSpace*> &fe)
198
    {
199
200
      FUNCNAME("FeSpaceData::getRankDofs()");

201
      int result = 0;
202
203
204
      for (unsigned int i = 0; i < fe.size(); i++) {
	TEST_EXIT_DBG(data.count(fe[i]))("Cannot find FE space: %p\n", fe[i]);
	result += data[fe[i]].nRankDofs;
205
206
207
208
209
      }

      return result;
    }

210
211
212
213
214
215
216
    inline int getRankDofs()
    {
      TEST_EXIT_DBG(nRankDofs >= 0)("Should not happen!\n");

      return nRankDofs;
    }

217
218
219
220
221
222
223
224
225
226
227
    int getOverallDofs(vector<const FiniteElemSpace*> &feSpaces)
    {
      int result = 0;
      for (unsigned int i = 0; i < feSpaces.size(); i++) {
	TEST_EXIT_DBG(data.count(feSpaces[i]))("Should not happen!\n");
	result += data.find(feSpaces[i])->second.nOverallDofs;
      }

      return result;
    }

228
229
230
231
232
233
234
    inline int getOverallDofs()
    {
      TEST_EXIT_DBG(nOverallDofs >= 0)("Should not happen!\n");

      return nOverallDofs;
    }

235
236
237
238
239
240
241
242
243
244
245
    int getStartDofs(vector<const FiniteElemSpace*> &feSpaces)
    {
      int result = 0;
      for (unsigned int i = 0; i < feSpaces.size(); i++) {
	TEST_EXIT_DBG(data.count(feSpaces[i]))("Should not happen!\n");
	result += data.find(feSpaces[i])->second.rStartDofs;
      }

      return result;
    }

246
247
248
249
250
251
252
    int getStartDofs()
    {
      TEST_EXIT_DBG(rStartDofs >= 0)("Should not happen!\n");

      return rStartDofs;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
253
254
255
    void init(MPI::Intracomm *m,
	      vector<const FiniteElemSpace*> &fe,
	      bool needGlobalMapping)
256
    {
Thomas Witkowski's avatar
Thomas Witkowski committed
257
      mpiComm = m;
258
      feSpaces = fe;
Thomas Witkowski's avatar
Thomas Witkowski committed
259
      for (unsigned int i = 0; i < feSpaces.size(); i++) {
260
	addFeSpace(feSpaces[i]);
Thomas Witkowski's avatar
Thomas Witkowski committed
261
262
	data[feSpaces[i]].setNeedGlobalMapping(needGlobalMapping);
      }
263
264
265
266
    }

    void update()
    {
Thomas Witkowski's avatar
Thomas Witkowski committed
267
268
269
//       for (unsigned int i = 0; i < feSpaces.size(); i++)
// 	data[feSpaces[i]].update();

270
271
272
273
274
275
276
277
278
279
      nRankDofs = getRankDofs(feSpaces);
      nOverallDofs = getOverallDofs(feSpaces);
      rStartDofs = getStartDofs(feSpaces);
    }

    inline int mapLocal(int index, int ithFeSpace)
    {
      int result = 0;
      for (int i = 0; i < ithFeSpace; i++)
	result += data[feSpaces[i]].nRankDofs;
Thomas Witkowski's avatar
Thomas Witkowski committed
280
      result += data[feSpaces[ithFeSpace]][index].local;
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

      return result;
    }

    inline int mapLocal(int index, const FiniteElemSpace *feSpace)
    {
      for (unsigned int i = 0; i < feSpaces.size(); i++)
	if (feSpaces[i] == feSpace)
	  return mapLocal(index, feSpace, i);

      return -1;
    }

    inline int mapGlobal(int index, int ithFeSpace)
    {
      int result = rStartDofs;
      for (int i = 0; i < ithFeSpace; i++)
	result += data[feSpaces[i]].nRankDofs;
Thomas Witkowski's avatar
Thomas Witkowski committed
299
      result += data[feSpaces[ithFeSpace]][index].local;
300
301
302
303
304
305
306
307
308
309
310
311
312

      return result;
    }

    inline int mapGlobal(int index, const FiniteElemSpace *feSpace)
    {
      for (unsigned int i = 0; i < feSpaces.size(); i++)
	if (feSpaces[i] == feSpace)
	  return mapGlobal(index, feSpace, i);

      return -1;
    }

313
314
315
316
  private:
    MPI::Intracomm* mpiComm;
    
    map<const FiniteElemSpace*, T> data;
317
318
319
320

    vector<const FiniteElemSpace*> feSpaces;

    int nRankDofs, nOverallDofs, rStartDofs;
321
322
323
324
325
  };

}

#endif