1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
89
90
91
92
93
94
95
96
97
98
99
100
101
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
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
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
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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
|
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
//
// MZone.cpp - Copyright (C) 2008 S. Guzik, C. Geuzaine, J.-F. Remacle
#include "GmshConfig.h"
#if defined(HAVE_LIBCGNS)
#include <iostream> // DBG
#include "MZone.h"
/*==============================================================================
* Forward declarations
*============================================================================*/
template <unsigned DIM>
struct ParseEntity;
/*******************************************************************************
*
* Routines from class MZone
*
******************************************************************************/
/*==============================================================================
*
* Routine: add_elements_in_entities
*
* Purpose
* =======
*
* Adds all (or only those of the right partition) elements in a container of
* entities to the zone.
*
* I/O
* ===
*
* <Ent> - The specific type of entity
* <EntIter> - The type of iterator for the entities
* begin - (I) Iterator to first entity
* end - (I) Iterator to last entity
* partition - (I) > 0 - only add elements of this partition to the
* zone
* = -1 - add all elements to the zone (default
* value)
*
*============================================================================*/
template <unsigned DIM>
template <typename EntIter>
void MZone<DIM>::add_elements_in_entities
(EntIter begin, EntIter end, const int partition)
{
// Find the neighbours of each vertex, edge, and face
for(EntIter itEnt = begin; itEnt != end; ++itEnt) {
ParseEntity<DIM>::eval(*itEnt, boFaceMap, elemVec, vertMap, zoneElemConn,
partition);
}
}
/*==============================================================================
*
* Routine: add_elements_in_entity
*
* Purpose
* =======
*
* Adds all (or only those of the right partition) elements in a single entity
* to the zone.
*
* I/O
* ===
*
* entity - (I) Pointer to the entity
* partition - (I) > 0 - only add elements of this partition to the
* zone
* = -1 - add all elements to the zone (default
* value)
*
* Notes
* =====
*
* - The entity pointer must be of a specific type (not a base class).
*
*============================================================================*/
template <unsigned DIM>
template <typename EntPtr>
void MZone<DIM>::add_elements_in_entity
(EntPtr entity, const int partition)
{
// Find the neighbours of each vertex, edge, and face
ParseEntity<DIM>::eval(entity, boFaceMap, elemVec, vertMap, zoneElemConn,
partition);
}
/*==============================================================================
*
* Routine: zoneData
*
* Purpose
* =======
*
* Processes all the elements in a zone. Stores vertices and element
* connectivity. Records boundary vertices for use with class
* 'MZoneBoundary'. Both the vertices and elements are ordered with boundary
* vertices/elements first.
*
*============================================================================*/
template <unsigned DIM>
int MZone<DIM>::zoneData()
{
if(elemVec.size() == 0) return 1;
// Resize output arrays
zoneVertVec.resize(vertMap.size());
//--Label boundary vertices and start building output vector of vertices.
//--Also record boundary faces that contain a boundary vertex.
std::vector<MVertex*> faceVertices;
unsigned cVert = 0;
for(typename BoFaceMap::iterator fMapIt = boFaceMap.begin();
fMapIt != boFaceMap.end(); ++fMapIt) {
// Get all the vertices on the face
DimTr<DIM>::getAllFaceVertices
(elemVec[fMapIt->second.parentElementIndex].element,
fMapIt->second.parentFace, faceVertices);
const int nVert = faceVertices.size();
for(int iVert = 0; iVert != nVert; ++iVert) {
int &index = vertMap[faceVertices[iVert]];
// Label the boundary vertices
if(index == 0) {
zoneVertVec[cVert] = faceVertices[iVert];
index = ++cVert;
}
// Record boundary faces that belong to boundary vertices
ZoneVertexData<typename BoFaceMap::const_iterator> &boVertData =
boVertMap[faceVertices[iVert]];
// const_cast is okay, the keys to 'boFaceMap' will not be changed
boVertData.faces.push_back(fMapIt);
boVertData.index = index;
}
}
numBoVert = cVert;
//--Label interior vertices and complete output vector of vertices
const VertexMap::iterator vMapEnd = vertMap.end();
for(VertexMap::iterator vMapIt = vertMap.begin();
vMapIt != vMapEnd; ++vMapIt) {
if(vMapIt->second == 0) { // Vertex in zone interior
zoneVertVec[cVert] = vMapIt->first;
vMapIt->second = ++cVert;
}
}
//--Initialize the connectivity array for the various types of elements. Note
//--that 'iElemType' is MSH_TYPE-1.
int numUsedElemType = 0;
for(int iElemType = 0; iElemType != MSH_NUM_TYPE; ++iElemType) {
if(zoneElemConn[iElemType].numElem > 0) {
zoneElemConn[iElemType].connectivity.resize
(zoneElemConn[iElemType].numElem*MElement::getInfoMSH(iElemType+1));
// Members numBoElem, and iConn should be set to zero via the constructor
// or a clear
}
}
//--The elements are added to the connectivity in two loops. The first loop
//--looks for boundary elements. The second loop adds the remaining interior
//--elements.
unsigned cElem = 1;
const ElementVec::const_iterator eVecEnd = elemVec.end();
for(ElementVec::iterator eVecIt = elemVec.begin(); eVecIt != eVecEnd;
++eVecIt) {
// It is sufficient to check the primary vertices to see if this element
// is on the boundary
const int nPVert = eVecIt->element->getNumPrimaryVertices();
for(int iPVert = 0; iPVert != nPVert; ++iPVert) {
if(vertMap[eVecIt->element->getVertex(iPVert)] <= numBoVert) {
// The element index
eVecIt->index = cElem++;
// The type of element
const int iElemType = eVecIt->element->getTypeForMSH() - 1;
// Increment number of boundary elements of this type
++zoneElemConn[iElemType].numBoElem;
// Load connectivity for this element type
const int nVert = eVecIt->element->getNumVertices();
for(int iVert = 0; iVert != nVert; ++iVert) {
zoneElemConn[iElemType].add_to_connectivity
(vertMap[eVecIt->element->getVertex(iVert)]);
}
break;
}
}
}
//--Now loop through all elements again and do same thing for all elements with
//--index set to 0
for(ElementVec::iterator eVecIt = elemVec.begin(); eVecIt != eVecEnd;
++eVecIt) {
if(eVecIt->index == 0) {
// The element index
eVecIt->index == cElem++;
// The type of element
const int iElemType = eVecIt->element->getTypeForMSH() - 1;
// Load connectivity for this element type
const int nVert = eVecIt->element->getNumVertices();
for(int iVert = 0; iVert != nVert; ++iVert) {
zoneElemConn[iElemType].add_to_connectivity
(vertMap[eVecIt->element->getVertex(iVert)]);
}
}
}
//**If we are going to write the boundary element faces, we need to update
//**.parentElementIndex from "index in elemVec" to "elemVec[iParent].index.
//**This is the index of the parent element local to the zone.
//--Clean-up for containers that are no longer required. Only 'boVertMap' is
//--still required but 'boFaceMap' is also retained because it contains the
//--faces referenced by 'boVertMap'.
elemVec.clear();
vertMap.clear();
return 0;
}
/*******************************************************************************
*
* Struct ParseEntity
*
* Purpose
* =======
*
* Iterates over the elements in an entity and adds them to the MZone.
*
******************************************************************************/
template <unsigned DIM>
struct ParseEntity
{
typedef typename DimTr<DIM>::FaceT FaceT; // The type/dimension of face
typedef typename LFaceTr<FaceT>::BoFaceMap BoFaceMap; // The corresponding map
static void eval(const GEntity *const entity,
BoFaceMap &boFaceMap,
ElementVec &elemVec,
VertexMap &vertMap,
ElementConnectivity *zoneElemConn,
const int partition)
{
unsigned numElem[5];
numElem[0] = 0; numElem[1] = 0; numElem[2] = 0; numElem[3] = 0; numElem[4] = 0;
entity->getNumMeshElements(numElem);
// Loop over all types of elements
int nType = entity->getNumElementTypes();
for(int iType = 0; iType != nType; ++iType) {
// Loop over all elements in a type
MElement *const *element = entity->getStartElementType(iType);
const int nElem = numElem[iType];
for(int iElem = 0; iElem != nElem; ++iElem) {
if(partition < 0 || element[iElem]->getPartition() == partition) {
// Unique list of elements
const unsigned eVecIndex = elemVec.size();
elemVec.push_back(ElemData(element[iElem]));
++zoneElemConn[(element[iElem])->getTypeForMSH() - 1].numElem;
// Unique list of vertices
const int nVert = element[iElem]->getNumVertices();
for(int iVert = 0; iVert != nVert; ++iVert)
vertMap[element[iElem]->getVertex(iVert)] = 0; // Unlabelled
// Maintain list of (base element) faces with only one bounding
// element.
const int nFace = DimTr<DIM>::getNumFace(element[iElem]);
for(int iFace = 0; iFace != nFace; ++iFace) {
FaceT face = DimTr<DIM>::getFace(element[iElem], iFace);
std::pair<typename BoFaceMap::iterator, bool> insBoFaceMap =
boFaceMap.insert(std::pair<FaceT, FaceData>
(face, FaceData(element[iElem], iFace,
eVecIndex)));
if(!insBoFaceMap.second) {
// The face already exists and is therefore bounded on both sides
// by elements. Not a boundary face so delete.
boFaceMap.erase(insBoFaceMap.first);
}
}
}
}
}
}
};
/*******************************************************************************
*
* Explicit instantiations of class MZone
*
******************************************************************************/
//--All the non-template routines in the class
template class MZone<2>;
template class MZone<3>;
//--Explicit instantiations of the routines for adding elements from a
//--container of entities
// Vector container
template void MZone<2>::add_elements_in_entities
<std::vector<GEntity*>::const_iterator>
(std::vector<GEntity*>::const_iterator begin,
std::vector<GEntity*>::const_iterator end, const int partition);
template void MZone<3>::add_elements_in_entities
<std::vector<GEntity*>::const_iterator>
(std::vector<GEntity*>::const_iterator begin,
std::vector<GEntity*>::const_iterator end, const int partition);
//--Explicit instantiations of the routines for adding elements from a single
//--entity
template void MZone<2>::add_elements_in_entity
<GFace*>
(GFace* entity, const int partition);
template void MZone<3>::add_elements_in_entity
<GRegion*>
(GRegion* entity, const int partition);
#endif
|