InteriorBoundary.cc 7.59 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
//
// 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.


13
#include "InteriorBoundary.h"
14
15
#include "FiniteElemSpace.h"
#include "BasisFunction.h"
16
#include "Serializer.h"
17
#include "VertexVector.h"
18
19

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

21
  void BoundaryObject::setReverseMode(BoundaryObject &otherBound, 
22
23
				      FiniteElemSpace *feSpace,
				      BoundaryType boundary)
24
25
26
27
28
29
30
  {
    FUNCNAME("BoundaryObject::setReverseMode()");

    bool otherMode = false;

    switch (feSpace->getMesh()->getDim()) {
    case 2:
31
      otherMode = true;
32
      break;
33

34
    case 3:
35
      TEST_EXIT_DBG(otherBound.elType == 0)
36
37
	("Only 3D macro elements with level 0 are supported. This element has level %d!\n", otherBound.elType);

38

39
40
41
42
43
44
45
46
47
48
49
50
      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);

51
52
53
54
55
56
57
58
59
	Mesh *mesh = feSpace->getMesh();

	if (mesh->isPeriodicAssociation(boundary) == false) {
	  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");
60

61
62
63
64
65
	  if (localDofs0[el0_v0] != localDofs1[el1_v0])
	    otherMode = true; 	
	} else {
	  if (mesh->associated(localDofs0[el0_v0], localDofs1[el1_v0]) == false)
	    otherMode = true;
66
67
68
69
70

	  if ((elIndex == 28 && otherBound.elIndex == 41) ||
	      (elIndex == 41 && otherBound.elIndex == 28)) {
	    MSG("HERE TEST B (%d %d): %d\n", el0_v0, el1_v0, otherMode);
	  }
71
	}
72
73
74
      }

      if (subObj == FACE && ithObj != 1) {
75
76
77
	const BasisFunction *basFcts = feSpace->getBasisFcts();
	int nBasFcts = basFcts->getNumber();
	std::vector<DegreeOfFreedom> localDofs0(nBasFcts), localDofs1(nBasFcts);
78
	basFcts->getLocalIndices(el, feSpace->getAdmin(), localDofs0);
79
	basFcts->getLocalIndices(otherBound.el, feSpace->getAdmin(), localDofs1);
80
81
82
83
84
	
	if (ithObj == 2 || ithObj == 3)
	  otherMode = (localDofs0[0] != localDofs1[0]);
	  
	if (ithObj == 0)
85
	  otherMode = (localDofs0[1] != localDofs1[1]);
86
87
      }
      break;
88

89
90
91
92
93
94
95
96
    default:
      ERROR_EXIT("This should not happen!\n");
    }

    otherBound.reverseMode = otherMode;
  }


97
98
99
  bool BoundaryObject::operator==(const BoundaryObject& other) const
  {
    return (other.elIndex == elIndex && 
100
	    //	    other.elType == elType &&
101
102
103
104
105
106
107
108
	    other.subObj == subObj && 
	    other.ithObj == ithObj);
  }


  bool BoundaryObject::operator!=(const BoundaryObject& other) const
  {
    return (other.elIndex != elIndex || 
109
	    //    other.elType != elType ||
110
111
112
113
114
	    other.subObj != subObj || 
	    other.ithObj != ithObj);
  }


115
116
117
118
119
120
121
122
  bool AtomicBoundary::operator==(const AtomicBoundary& other) const
  {
    return (rankObj == other.rankObj && 
	    neighObj == other.neighObj && 
	    type == other.type);
  }


123
  AtomicBoundary& InteriorBoundary::getNewAtomic(int rank)
Thomas Witkowski's avatar
Thomas Witkowski committed
124
125
126
127
128
  {
    boundary[rank].resize(boundary[rank].size() + 1);
    return boundary[rank][boundary[rank].size() - 1];
  }

129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  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;
  }


156
157
  void InteriorBoundary::serialize(std::ostream &out)
  {
158
159
    FUNCNAME("InteriorBoundary::serialize()");

160
    int mSize = boundary.size();
161
    SerUtil::serialize(out, mSize);
162
163
164
    for (RankToBoundMap::iterator it = boundary.begin(); it != boundary.end(); ++it) {
      int rank = it->first;
      int boundSize = it->second.size();
165
166
      SerUtil::serialize(out, rank);
      SerUtil::serialize(out, boundSize);
167
168
169
      for (int i = 0; i < boundSize; i++) {
	AtomicBoundary &bound = (it->second)[i];

170
	SerUtil::serialize(out, bound.rankObj.elIndex);
171
	SerUtil::serialize(out, bound.rankObj.elType);
172
173
	SerUtil::serialize(out, bound.rankObj.subObj);
	SerUtil::serialize(out, bound.rankObj.ithObj);
174
	SerUtil::serialize(out, bound.rankObj.reverseMode);
175
	serializeExcludeList(out, bound.rankObj.excludedSubstructures);
176

177
	SerUtil::serialize(out, bound.neighObj.elIndex);
178
	SerUtil::serialize(out, bound.neighObj.elType);
179
180
	SerUtil::serialize(out, bound.neighObj.subObj);
	SerUtil::serialize(out, bound.neighObj.ithObj);
181
	SerUtil::serialize(out, bound.neighObj.reverseMode);
182
	serializeExcludeList(out, bound.neighObj.excludedSubstructures);
183
184

	SerUtil::serialize(out, bound.type);
185
186
      }
    }
187
188
  }

189

190
191
  void InteriorBoundary::deserialize(std::istream &in, 
				     std::map<int, Element*> &elIndexMap)
192
  {
193
194
    FUNCNAME("InteriorBoundary::deserialize()");

195
    int mSize = 0;
196
    SerUtil::deserialize(in, mSize);
197
198
199
    for (int i = 0; i < mSize; i++) {
      int rank = 0;
      int boundSize = 0;
200
201
      SerUtil::deserialize(in, rank);
      SerUtil::deserialize(in, boundSize);
202
203
204
205
206

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

207
	SerUtil::deserialize(in, bound.rankObj.elIndex);
208
	SerUtil::deserialize(in, bound.rankObj.elType);
209
210
	SerUtil::deserialize(in, bound.rankObj.subObj);
	SerUtil::deserialize(in, bound.rankObj.ithObj);
211
	SerUtil::deserialize(in, bound.rankObj.reverseMode);
212
	deserializeExcludeList(in, bound.rankObj.excludedSubstructures);
213

214
	SerUtil::deserialize(in, bound.neighObj.elIndex);
215
	SerUtil::deserialize(in, bound.neighObj.elType);
216
217
	SerUtil::deserialize(in, bound.neighObj.subObj);
	SerUtil::deserialize(in, bound.neighObj.ithObj);
218
	SerUtil::deserialize(in, bound.neighObj.reverseMode);
219
	deserializeExcludeList(in, bound.neighObj.excludedSubstructures);
220

221
222
	SerUtil::deserialize(in, bound.type);

223
224
225
226
	TEST_EXIT_DBG(elIndexMap.count(bound.rankObj.elIndex) == 1)
	  ("Cannot find element with index %d for deserialization!\n", 
	   bound.rankObj.elIndex);

227
228
229
	TEST_EXIT_DBG(elIndexMap[bound.rankObj.elIndex]->getIndex() == 
		      bound.rankObj.elIndex)("Should not happen!\n");

230
231
	bound.rankObj.el = elIndexMap[bound.rankObj.elIndex];
	bound.neighObj.el = NULL;
232
233
      }
    }
234
  }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264


  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));
    }
  }

265
}