ParallelDofMapping.h 7.7 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
#include "parallel/MpiHelper.h"
#include "parallel/ParallelTypes.h"
29
#include "parallel/StdMpi.h"
30
31
32
33
34
35
36

#ifndef AMDIS_FE_SPACE_MAPPING_H
#define AMDIS_FE_SPACE_MAPPING_H

namespace AMDiS {
  using namespace std;

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

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  /** \brief
   * Defines for each system component a mapping for sets of global DOF indices
   * to global matrix indices. The mapping is defined for all DOFs in rank's 
   * subdomain. When periodic boundary conditions are used, then the mapping
   * stores also information for the periodic associations of rank's DOF on
   * periodic boundaries.
   */
  class DofToMatIndex
  {
  public:
    DofToMatIndex() {}

    /// Reset the data structure.
    inline void clear()
    {
      data.clear();
    }

    /// Add a new mapping.
    inline void add(int component, DegreeOfFreedom dof, int globalMatIndex)
    {
      data[component][dof] = globalMatIndex;
    }

    /// Map a global DOF index to the global matrix index for a specific 
    /// system component number.
    inline int get(int component, DegreeOfFreedom dof)
    {
      FUNCNAME("DofToMatIndex::get()");

      TEST_EXIT_DBG(data.count(component))
	("No mapping data for component %d available!\n", component);

      TEST_EXIT_DBG(data[component].count(dof))
	("Mapping for DOF %d in component %d does not exists!\n",
	 dof, component);

      return data[component][dof];
    }

  private:
    /// The mapping data. For each system component there is a specific map that
    /// maps global DOF indices to global matrix indices.
    map<int, map<DegreeOfFreedom, int> > data;
  };


89
90
91
  class GlobalDofMap
  {
  public:
92
93
94
95
96
97
98
    /// 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");
    }
      
99
100
    GlobalDofMap(MPI::Intracomm* m)
      : mpiComm(m),
Thomas Witkowski's avatar
Thomas Witkowski committed
101
102
	sendDofs(NULL),
	recvDofs(NULL),
103
	feSpace(NULL),
Thomas Witkowski's avatar
Thomas Witkowski committed
104
	needGlobalMapping(false),
105
	nRankDofs(0),
Thomas Witkowski's avatar
Thomas Witkowski committed
106
	nLocalDofs(0),
107
	nOverallDofs(0),
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
108
	rStartDofs(0),
109
	hasNonLocalDofs(false)
110
111
    {}
    
112
    void clear();
113
    
Thomas Witkowski's avatar
Thomas Witkowski committed
114
    MultiIndex& operator[](DegreeOfFreedom d)
115
116
117
118
119
120
    {
      TEST_EXIT_DBG(dofMap.count(d))("Should not happen!\n");

      return dofMap[d];
    }
    
Thomas Witkowski's avatar
Thomas Witkowski committed
121
    void insertRankDof(DegreeOfFreedom dof0, DegreeOfFreedom dof1 = -1)
122
123
124
125
126
    {
      FUNCNAME("GlobalDofMap::insertRankDof()");
      
      TEST_EXIT_DBG(dofMap.count(dof0) == 0)("Should not happen!\n");
      
Thomas Witkowski's avatar
Thomas Witkowski committed
127
      dofMap[dof0].local = dof1;
Thomas Witkowski's avatar
Thomas Witkowski committed
128
      nLocalDofs++;
Thomas Witkowski's avatar
Thomas Witkowski committed
129
130
      if (dof1 != -1)
	nRankDofs++;
131
132
    }
    
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
133
    void insert(DegreeOfFreedom dof0, DegreeOfFreedom dof1 = -1)
134
135
136
137
138
    {
      FUNCNAME("GlobalDofMap::insert()");
      
      TEST_EXIT_DBG(dofMap.count(dof0) == 0)("Should not happen!\n");
      
Thomas Witkowski's avatar
Thomas Witkowski committed
139
      dofMap[dof0].local = dof1;
Thomas Witkowski's avatar
Thomas Witkowski committed
140
      nLocalDofs++;
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
141
      nonRankDofs.insert(dof0);
142
143
144
145
146
147
    }
    
    bool isSet(DegreeOfFreedom dof)
    {
      return static_cast<bool>(dofMap.count(dof));
    }
148
149
150
151
152

    bool isRankDof(DegreeOfFreedom dof)
    {
      return !(static_cast<bool>(nonRankDofs.count(dof)));
    }
153
154
155
156
157
158
    
    unsigned int size()
    {
      return dofMap.size();
    }
    
Thomas Witkowski's avatar
Thomas Witkowski committed
159
    map<DegreeOfFreedom, MultiIndex>& getMap()
160
161
162
163
    {
      return dofMap;
    }
    
Thomas Witkowski's avatar
Thomas Witkowski committed
164
    void update();
165

166
    void computeGlobalMapping(int offset);
167

Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
168
169
170
171
172
173
174
175
176
    void computeNonLocalIndices();

    void print();

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

177
    void setNonLocalDofs(bool b)
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
178
    {
179
      hasNonLocalDofs = b;
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
180
181
    }

182
    void setNeedGlobalMapping(bool b)
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
183
    {
184
      needGlobalMapping = b;
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
185
186
    }

187
    void setDofComm(DofComm &pSend, DofComm &pRecv)
Thomas Witkowski's avatar
Thomas Witkowski committed
188
    {
189
190
      sendDofs = &pSend;
      recvDofs = &pRecv;
Thomas Witkowski's avatar
Thomas Witkowski committed
191
192
    }

193
194
  private:
    MPI::Intracomm* mpiComm;
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
195

196
197
198
199
    DofComm *sendDofs;
    
    DofComm *recvDofs;

Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
200
201
    const FiniteElemSpace *feSpace;

202
    /// 
Thomas Witkowski's avatar
Thomas Witkowski committed
203
    map<DegreeOfFreedom, MultiIndex> dofMap;
204

Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
205
206
    std::set<DegreeOfFreedom> nonRankDofs;

Thomas Witkowski's avatar
Thomas Witkowski committed
207
    bool needGlobalMapping;
208
209
  public:
    /// 
Thomas Witkowski's avatar
Thomas Witkowski committed
210
    int nRankDofs, nLocalDofs, nOverallDofs, rStartDofs;
Thomas Witkowski's avatar
FETI-DP  
Thomas Witkowski committed
211

212
213
214
215
    /// Is true if there are DOFs in at least one subdomain that are not owned
    /// by the rank. If the value is false, each rank contains only DOFs that
    /// are also owned by this rank.
    bool hasNonLocalDofs;
216
217
218
  };
  

Thomas Witkowski's avatar
Thomas Witkowski committed
219
  class ParallelDofMapping
220
221
  {
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
222
    ParallelDofMapping() 
223
      : mpiComm(NULL),
224
225
	sendDofs(NULL),
	recvDofs(NULL),
226
	hasNonLocalDofs(false),
227
228
229
230
231
	feSpaces(0),
	nRankDofs(-1),
	nOverallDofs(-1),
	rStartDofs(-1)
    {} 
232

Thomas Witkowski's avatar
Thomas Witkowski committed
233
    inline GlobalDofMap& operator[](const FiniteElemSpace* feSpace)
234
    {
Thomas Witkowski's avatar
Thomas Witkowski committed
235
      FUNCNAME("ParallelDofMapping::operator[]()");
236
237
238
239
240
241

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
242
    void addFeSpace(const FiniteElemSpace* feSpace);
243

Thomas Witkowski's avatar
Thomas Witkowski committed
244
    int getRankDofs(vector<const FiniteElemSpace*> &fe);
245

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

      return nRankDofs;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
253
    int getLocalDofs(vector<const FiniteElemSpace*> &fe);
Thomas Witkowski's avatar
Thomas Witkowski committed
254
255
256
257
258
259
260
261

    inline int getLocalDofs()
    {
      TEST_EXIT_DBG(nLocalDofs >= 0)("Should not happen!\n");

      return nLocalDofs;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
262
    int getOverallDofs(vector<const FiniteElemSpace*> &feSpaces);
263

264
265
266
267
268
269
270
    inline int getOverallDofs()
    {
      TEST_EXIT_DBG(nOverallDofs >= 0)("Should not happen!\n");

      return nOverallDofs;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
271
    int getStartDofs(vector<const FiniteElemSpace*> &feSpaces);
272

Thomas Witkowski's avatar
Thomas Witkowski committed
273
    inline int getStartDofs()
274
275
276
277
278
279
    {
      TEST_EXIT_DBG(rStartDofs >= 0)("Should not happen!\n");

      return rStartDofs;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
280
281
    void init(MPI::Intracomm *m,
	      vector<const FiniteElemSpace*> &fe,
282
	      bool needGlobalMapping,
Thomas Witkowski's avatar
Thomas Witkowski committed
283
	      bool bNonLocalDofs);
284

Thomas Witkowski's avatar
Thomas Witkowski committed
285
    void update();
286

Thomas Witkowski's avatar
Thomas Witkowski committed
287
    void computeMatIndex();
288

Thomas Witkowski's avatar
Thomas Witkowski committed
289
    void setDofComm(DofComm &pSend, DofComm &pRecv);
290

Thomas Witkowski's avatar
Thomas Witkowski committed
291
292
293
294
295
    inline int getMatIndex(int ithComponent, DegreeOfFreedom d)
    {
      return dofToMatIndex.get(ithComponent, d);
    }

296
297
    inline int getLocalMatIndex(int ithComponent, DegreeOfFreedom d)
    {
Thomas Witkowski's avatar
Thomas Witkowski committed
298
      FUNCNAME("ParallelDofMapping::getLocalMatIndex()");
299
300
301
302
303
304
305

      TEST_EXIT_DBG(data[feSpaces[ithComponent]].isRankDof(d))
	("Should not happen!\n");

      return dofToMatIndex.get(ithComponent, d) - rStartDofs;
    }

306
307
  private:
    MPI::Intracomm* mpiComm;
308
309
310
311
312

    DofComm *sendDofs;
    
    DofComm *recvDofs;

313
314
315
316
    /// Is true if there are DOFs in at least one subdomain that are not owned
    /// by the rank. If the value is false, each rank contains only DOFs that
    /// are also owned by this rank.
    bool hasNonLocalDofs;
317
    
Thomas Witkowski's avatar
Thomas Witkowski committed
318
    map<const FiniteElemSpace*, GlobalDofMap> data;
319
320
321

    vector<const FiniteElemSpace*> feSpaces;

Thomas Witkowski's avatar
Thomas Witkowski committed
322
323
324
    std::set<const FiniteElemSpace*> feSpacesUnique;

    int nRankDofs, nLocalDofs, nOverallDofs, rStartDofs;
325
326
327
328

    /// Mapping from global DOF indices to global matrix indices under 
    /// consideration of possibly multiple components.
    DofToMatIndex dofToMatIndex;
329
330
331
332
333
  };

}

#endif