InteriorBoundary.cc 6.87 KB
Newer Older
1
#include "InteriorBoundary.h"
2
3
#include "FiniteElemSpace.h"
#include "BasisFunction.h"
4
#include "Serializer.h"
5
6

namespace AMDiS {
Thomas Witkowski's avatar
Thomas Witkowski committed
7

8
9
10
11
12
13
14
15
16
  void BoundaryObject::setReverseMode(BoundaryObject &otherBound, 
				      FiniteElemSpace *feSpace)
  {
    FUNCNAME("BoundaryObject::setReverseMode()");

    bool otherMode = false;

    switch (feSpace->getMesh()->getDim()) {
    case 2:
17
      otherMode = true;
18
      break;
19

20
    case 3:
21
22
23
      TEST_EXIT_DBG(otherBound.elType == 0)
	("Only 3D macro elements with level 0 are supported!\n");

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
      if (subObj == EDGE) {	
	int el0_v0 = el->getVertexOfEdge(ithObj, 0);
	int el0_v1 = el->getVertexOfEdge(ithObj, 1);
	int el1_v0 = el->getVertexOfEdge(otherBound.ithObj, 0);
	int el1_v1 = el->getVertexOfEdge(otherBound.ithObj, 1);

	const BasisFunction *basFcts = feSpace->getBasisFcts();
	int nBasFcts = basFcts->getNumber();
	std::vector<DegreeOfFreedom> localDofs0(nBasFcts), localDofs1(nBasFcts);
	basFcts->getLocalIndices(el, feSpace->getAdmin(), localDofs0);
	basFcts->getLocalIndices(otherBound.el, feSpace->getAdmin(), localDofs1);

	TEST_EXIT_DBG(localDofs0[el0_v0] == localDofs1[el1_v0] ||
		      localDofs0[el0_v0] == localDofs1[el1_v1])
	  ("This should not happen!\n");
	TEST_EXIT_DBG(localDofs0[el0_v1] == localDofs1[el1_v0] ||
		      localDofs0[el0_v1] == localDofs1[el1_v1])
	  ("This should not happen!\n");
	
 	if (localDofs0[el0_v0] != localDofs1[el1_v0])
	  otherMode = true; 	
      }

      if (subObj == FACE && ithObj != 1) {
48
49
50
	const BasisFunction *basFcts = feSpace->getBasisFcts();
	int nBasFcts = basFcts->getNumber();
	std::vector<DegreeOfFreedom> localDofs0(nBasFcts), localDofs1(nBasFcts);
51
	basFcts->getLocalIndices(el, feSpace->getAdmin(), localDofs0);
52
	basFcts->getLocalIndices(otherBound.el, feSpace->getAdmin(), localDofs1);
53
54
55
56
57
	
	if (ithObj == 2 || ithObj == 3)
	  otherMode = (localDofs0[0] != localDofs1[0]);
	  
	if (ithObj == 0)
58
	  otherMode = (localDofs0[1] != localDofs1[1]);
59
60
      }
      break;
61

62
63
64
65
66
67
68
69
    default:
      ERROR_EXIT("This should not happen!\n");
    }

    otherBound.reverseMode = otherMode;
  }


70
71
72
  bool BoundaryObject::operator==(const BoundaryObject& other) const
  {
    return (other.elIndex == elIndex && 
73
	    //	    other.elType == elType &&
74
75
76
77
78
79
80
81
	    other.subObj == subObj && 
	    other.ithObj == ithObj);
  }


  bool BoundaryObject::operator!=(const BoundaryObject& other) const
  {
    return (other.elIndex != elIndex || 
82
	    //    other.elType != elType ||
83
84
85
86
87
	    other.subObj != subObj || 
	    other.ithObj != ithObj);
  }


88
89
90
91
92
93
94
95
  bool AtomicBoundary::operator==(const AtomicBoundary& other) const
  {
    return (rankObj == other.rankObj && 
	    neighObj == other.neighObj && 
	    type == other.type);
  }


96
  AtomicBoundary& InteriorBoundary::getNewAtomic(int rank)
Thomas Witkowski's avatar
Thomas Witkowski committed
97
98
99
100
101
  {
    boundary[rank].resize(boundary[rank].size() + 1);
    return boundary[rank][boundary[rank].size() - 1];
  }

102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  bool InteriorBoundary::operator==(const InteriorBoundary& other) const
  {
    InteriorBoundary& other2 = const_cast<InteriorBoundary&>(other);

    for (RankToBoundMap::const_iterator it = boundary.begin(); 
	 it != boundary.end(); ++it) {
      if (other2.boundary.count(it->first) == 0)
	return false;     

      if (other2.boundary[it->first].size() != it->second.size())
	return false;
            
      for (unsigned int i = 0; i < it->second.size(); i++) {
	std::vector<AtomicBoundary>::iterator bIt = 
	  find(other2.boundary[it->first].begin(),
	       other2.boundary[it->first].end(), it->second[i]);
	
	if (bIt == other2.boundary[it->first].end())
	  return false;	
      }      
    }

    return true;
  }


129
130
  void InteriorBoundary::serialize(std::ostream &out)
  {
131
132
    FUNCNAME("InteriorBoundary::serialize()");

133
    int mSize = boundary.size();
134
    SerUtil::serialize(out, mSize);
135
136
137
    for (RankToBoundMap::iterator it = boundary.begin(); it != boundary.end(); ++it) {
      int rank = it->first;
      int boundSize = it->second.size();
138
139
      SerUtil::serialize(out, rank);
      SerUtil::serialize(out, boundSize);
140
141
142
      for (int i = 0; i < boundSize; i++) {
	AtomicBoundary &bound = (it->second)[i];

143
	SerUtil::serialize(out, bound.rankObj.elIndex);
144
	SerUtil::serialize(out, bound.rankObj.elType);
145
146
	SerUtil::serialize(out, bound.rankObj.subObj);
	SerUtil::serialize(out, bound.rankObj.ithObj);
147
	SerUtil::serialize(out, bound.rankObj.reverseMode);
148
	serializeExcludeList(out, bound.rankObj.excludedSubstructures);
149

150
	SerUtil::serialize(out, bound.neighObj.elIndex);
151
	SerUtil::serialize(out, bound.neighObj.elType);
152
153
	SerUtil::serialize(out, bound.neighObj.subObj);
	SerUtil::serialize(out, bound.neighObj.ithObj);
154
	SerUtil::serialize(out, bound.neighObj.reverseMode);
155
	serializeExcludeList(out, bound.neighObj.excludedSubstructures);
156
157

	SerUtil::serialize(out, bound.type);
158
159
      }
    }
160
161
  }

162

163
164
  void InteriorBoundary::deserialize(std::istream &in, 
				     std::map<int, Element*> &elIndexMap)
165
  {
166
167
    FUNCNAME("InteriorBoundary::deserialize()");

168
    int mSize = 0;
169
    SerUtil::deserialize(in, mSize);
170
171
172
    for (int i = 0; i < mSize; i++) {
      int rank = 0;
      int boundSize = 0;
173
174
      SerUtil::deserialize(in, rank);
      SerUtil::deserialize(in, boundSize);
175
176
177
178
179

      boundary[rank].resize(boundSize);
      for (int i = 0; i < boundSize; i++) {
	AtomicBoundary &bound = boundary[rank][i];

180
	SerUtil::deserialize(in, bound.rankObj.elIndex);
181
	SerUtil::deserialize(in, bound.rankObj.elType);
182
183
	SerUtil::deserialize(in, bound.rankObj.subObj);
	SerUtil::deserialize(in, bound.rankObj.ithObj);
184
	SerUtil::deserialize(in, bound.rankObj.reverseMode);
185
	deserializeExcludeList(in, bound.rankObj.excludedSubstructures);
186

187
	SerUtil::deserialize(in, bound.neighObj.elIndex);
188
	SerUtil::deserialize(in, bound.neighObj.elType);
189
190
	SerUtil::deserialize(in, bound.neighObj.subObj);
	SerUtil::deserialize(in, bound.neighObj.ithObj);
191
	SerUtil::deserialize(in, bound.neighObj.reverseMode);
192
	deserializeExcludeList(in, bound.neighObj.excludedSubstructures);
193

194
195
	SerUtil::deserialize(in, bound.type);

196
197
198
199
	TEST_EXIT_DBG(elIndexMap.count(bound.rankObj.elIndex) == 1)
	  ("Cannot find element with index %d for deserialization!\n", 
	   bound.rankObj.elIndex);

200
201
202
	TEST_EXIT_DBG(elIndexMap[bound.rankObj.elIndex]->getIndex() == 
		      bound.rankObj.elIndex)("Should not happen!\n");

203
204
	bound.rankObj.el = elIndexMap[bound.rankObj.elIndex];
	bound.neighObj.el = NULL;
205
206
      }
    }
207
  }
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237


  void InteriorBoundary::serializeExcludeList(std::ostream &out, ExcludeList &list)
  {
    int size = list.size();
    SerUtil::serialize(out, size);
    for (int i = 0; i < size; i++) {
      SerUtil::serialize(out, list[i].first);
      SerUtil::serialize(out, list[i].second);
    }
  }


  void InteriorBoundary::deserializeExcludeList(std::istream &in, ExcludeList &list)
  {
    int size = 0;
    SerUtil::deserialize(in, size);
    list.resize(0);
    list.reserve(size);

    for (int i = 0; i < size; i++) {
      GeoIndex a;
      int b;

      SerUtil::deserialize(in, a);
      SerUtil::deserialize(in, b);
      list.push_back(std::make_pair(a, b));
    }
  }

238
}