DofComm.cc 5.32 KB
Newer Older
1
2
3
4
5
6
7
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
8
 * Authors:
9
10
11
12
13
14
15
16
17
 * 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.
18
 *
19
 ******************************************************************************/
20
21


22
23
#include "parallel/DofComm.h"
#include "parallel/InteriorBoundary.h"
24
#include "parallel/MeshLevelData.h"
25
#include "FiniteElemSpace.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
26
27
#include "Debug.h"
#include "ElementDofIterator.h"
28
#include "DOFVector.h"
29

30
namespace AMDiS { namespace Parallel {
31
32
33

  using namespace std;

34

35
  void DofComm::init(vector<const FiniteElemSpace*> &fe)
36
37
  {
    feSpaces = fe;
38
    mesh = feSpaces[0]->getMesh();
39

40
41
    sendDofs.clear();
    recvDofs.clear();
42
    periodicDofs.clear();
43
44
  }

45
  void DofComm::create(Mesh* mesh, InteriorBoundary &boundary)
46
  {
47
    FUNCNAME("DofComm::create()");
48
    TEST_EXIT(mesh == this->mesh) ("No equal mesh.\n");
49

50
51
    sendDofs.clear();
    recvDofs.clear();
52
53
    periodicDofs.clear();

54
55
56
    createContainer(mesh, boundary, boundary.getOwn(), sendDofs);
    createContainer(mesh, boundary, boundary.getOther(), recvDofs);

57
#ifndef NDEBUG
58
59
60
61
62
63
64
65
66
67
68
69
70
    {
      std::set<DegreeOfFreedom> sds;
      for (DofComm::Iterator it(sendDofs, feSpaces[0]);
         !it.end(); it.nextRank())
      for (; !it.endDofIter(); it.nextDof())
         sds.insert(it.getDofIndex());

      for (DofComm::Iterator it2(recvDofs, feSpaces[0]);
         !it2.end(); it2.nextRank())
        for (; !it2.endDofIter(); it2.nextDof())
          TEST_EXIT(!sds.count(it2.getDofIndex()))("Send and recv have same dofs.\n");
    }
#endif
71
72
73
  }


74
75
76
77

  void DofComm::createContainer(Mesh* mesh,
				InteriorBoundary &boundary,
                                RankToBoundMap &rankToBoundMap,
78
				DataType &data)
79
80
81
82
  {
    // === Fill data. ===

    for (unsigned int i = 0; i < feSpaces.size(); i++)
83
      for (InteriorBoundary::iterator it(rankToBoundMap); !it.end(); ++it)
84
85
	boundary.getElementPtr(it->rankObj.elIndex, mesh)
	  ->getAllDofs(feSpaces[i], it->rankObj, data[it.getRank()][feSpaces[i]]);
86
87

    // === Remove empty data containers. ===
88

89
90
91
92
93
94
95
96
97
98
99
    DataIter dit = data.begin();
    while (dit != data.end()) {
      FeMapIter it = dit->second.begin();
      while (it != dit->second.end()) {
	if (it->second.size() == 0) {
	  const FiniteElemSpace *fe = it->first;
	  ++it;
	  dit->second.erase(fe);
	} else
	  ++it;
      }
100

101
102
103
104
      if (dit->second.size() == 0)
	data.erase(dit++);
      else
	++dit;
105
106
107
    }
  }

108

Thomas Witkowski's avatar
Thomas Witkowski committed
109
110
111
112
  void DofComm::serialize(ostream &out)
  {
    FUNCNAME("DofComm:serialize()");

Thomas Witkowski's avatar
Thomas Witkowski committed
113
    ERROR_EXIT("MUSS DAS WIRKLICH SEIN????\n");
Thomas Witkowski's avatar
Thomas Witkowski committed
114
115
  }

116
117

  int DofComm::getNumberDofs(DataType &data,
Thomas Witkowski's avatar
Blub    
Thomas Witkowski committed
118
119
			     const FiniteElemSpace *feSpace,
			     bool countDouble)
120
  {
Thomas Witkowski's avatar
Blub    
Thomas Witkowski committed
121
122
    DofContainerSet dofSet;
    DofContainer dofVec;
123

124
    for (DataIter rankIt = data.begin(); rankIt != data.end(); ++rankIt) {
125
      for (FeMapIter feIt = rankIt->second.begin();
126
127
128
	   feIt != rankIt->second.end(); ++feIt) {
	if (feIt->first == feSpace) {
	  if (countDouble) {
Thomas Witkowski's avatar
Blub    
Thomas Witkowski committed
129
	    dofVec.insert(dofVec.end(), feIt->second.begin(), feIt->second.end());
130
	  } else {
Thomas Witkowski's avatar
Blub    
Thomas Witkowski committed
131
	    dofSet.insert(feIt->second.begin(), feIt->second.end());
132
133
134
135
	  }
	}
      }
    }
Thomas Witkowski's avatar
Blub    
Thomas Witkowski committed
136
137

    if (countDouble)
138
      return static_cast<int>(dofVec.size());
Thomas Witkowski's avatar
Blub    
Thomas Witkowski committed
139
    return static_cast<int>(dofSet.size());
140
141
  }

142
143

  int DofComm::getDegree(const FiniteElemSpace *feSpace,
144
145
146
147
			 const DegreeOfFreedom *dof)
  {
    int degree = 0;

Thomas Witkowski's avatar
Thomas Witkowski committed
148
149
    for (map<int, FeMapType>::iterator it = sendDofs.begin();
	 it != sendDofs.end(); ++it) {
150
151
152
153
154
      DofContainer &dc = it->second[feSpace];
      if (find(dc.begin(), dc.end(), dof) != dc.end())
	degree++;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
155
156
    for (map<int, FeMapType>::iterator it = recvDofs.begin();
	 it != recvDofs.end(); ++it) {
157
158
159
160
161
162
163
164
165
      DofContainer &dc = it->second[feSpace];
      if (find(dc.begin(), dc.end(), dof) != dc.end())
	degree++;
    }

    return degree;
  }


166
  bool DofComm::Iterator::setNextFeMap()
167
  {
168
    FUNCNAME_DBG("DofComm::Iterator::setNextFeMap()");
169

170
    if (dataIter != data.end()) {
171
172
      TEST_EXIT_DBG(dataIter->second.size())("Should not happen!\n");

173
      feMapIter = dataIter->second.begin();
174

175
      if (traverseFeSpace != NULL) {
176
177
	if ((dataIter->second.count(traverseFeSpace) == 0))
	  return false;
178

179
180
181
	while (feMapIter->first != traverseFeSpace &&
	       feMapIter != dataIter->second.end())
	  ++feMapIter;
182

183
184
185
186
	TEST_EXIT_DBG(feMapIter != dataIter->second.end() &&
		      feMapIter->first == traverseFeSpace)
	  ("Should not happen!\n");
      }
187
188

      dofIter = feMapIter->second.begin();
189
190
      dofCounter = 0;
    }
191
192

    return true;
193
194
  }

195
196
197
198
199
200
201
202
203

  void MultiLevelDofComm::init(MeshLevelData &levelData,
			       vector<const FiniteElemSpace*> &fe)
  {
    int nLevel = levelData.getNumberOfLevels();
    for (int level = 0; level < nLevel; level++)
      levelDofComm[level].init(fe);
  }

204
  void MultiLevelDofComm::create(Mesh* mesh, MultiLevelInteriorBoundary &boundary)
205
206
207
  {
    for (map<int, DofComm>::iterator it = levelDofComm.begin();
	 it != levelDofComm.end(); ++it)
208
      it->second.create(mesh, boundary[it->first]);
209
210
  }

211
} }