ensightPartCells.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "ensightPartCells.H"
27 #include "IOstream.H"
28 #include "IStringStream.H"
29 #include "dictionary.H"
30 #include "cellModeller.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(ensightPartCells, 0);
38  addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream);
39 }
40 
42 (
43  IStringStream
44  (
45  "(tetra4 pyramid5 penta6 hexa8 nfaced)"
46  )()
47 );
48 
49 
50 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51 
52 void Foam::ensightPartCells::classify
53 (
54  const polyMesh& mesh,
55  const labelUList& idList
56 )
57 {
58  // References to cell shape models
59  const cellModel& tet = *(cellModeller::lookup("tet"));
60  const cellModel& pyr = *(cellModeller::lookup("pyr"));
61  const cellModel& prism = *(cellModeller::lookup("prism"));
62  const cellModel& hex = *(cellModeller::lookup("hex"));
63 
64  const cellShapeList& cellShapes = mesh.cellShapes();
65 
66  offset_ = 0;
67  size_ = mesh.nCells();
68 
69  bool limited = false;
70  if (notNull(idList))
71  {
72  limited = true;
73  size_ = idList.size();
74  }
75 
76  // count the shapes
77  label nTet = 0;
78  label nPyr = 0;
79  label nPrism = 0;
80  label nHex = 0;
81  label nPoly = 0;
82 
83  for (label listI = 0; listI < size_; ++listI)
84  {
85  label cellId = listI;
86  if (limited)
87  {
88  cellId = idList[listI];
89  }
90 
91  const cellShape& cellShape = cellShapes[cellId];
92  const cellModel& cellModel = cellShape.model();
93 
94  if (cellModel == tet)
95  {
96  nTet++;
97  }
98  else if (cellModel == pyr)
99  {
100  nPyr++;
101  }
102  else if (cellModel == prism)
103  {
104  nPrism++;
105  }
106  else if (cellModel == hex)
107  {
108  nHex++;
109  }
110  else
111  {
112  nPoly++;
113  }
114  }
115 
116 
117  // we can avoid double looping, but at the cost of allocation
118  labelList tetCells(nTet);
119  labelList pyramidCells(nPyr);
120  labelList prismCells(nPrism);
121  labelList hexCells(nHex);
122  labelList polyCells(nPoly);
123 
124  nTet = 0,
125  nPyr = 0;
126  nPrism = 0;
127  nHex = 0;
128  nPoly = 0;
129 
130  // classify the shapes
131  for (label listI = 0; listI < size_; ++listI)
132  {
133  label cellId = listI;
134  if (limited)
135  {
136  cellId = idList[listI];
137  }
138 
139  const cellShape& cellShape = cellShapes[cellId];
140  const cellModel& cellModel = cellShape.model();
141 
142  if (cellModel == tet)
143  {
144  tetCells[nTet++] = cellId;
145  }
146  else if (cellModel == pyr)
147  {
148  pyramidCells[nPyr++] = cellId;
149  }
150  else if (cellModel == prism)
151  {
152  prismCells[nPrism++] = cellId;
153  }
154  else if (cellModel == hex)
155  {
156  hexCells[nHex++] = cellId;
157  }
158  else
159  {
160  polyCells[nPoly++] = cellId;
161  }
162  }
163 
164 
165  // MUST match with elementTypes
166  elemLists_.setSize(elementTypes().size());
167 
168  elemLists_[tetra4Elements].transfer(tetCells);
169  elemLists_[pyramid5Elements].transfer(pyramidCells);
170  elemLists_[penta6Elements].transfer(prismCells);
171  elemLists_[hexa8Elements].transfer(hexCells);
172  elemLists_[nfacedElements].transfer(polyCells);
173 }
174 
175 
176 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
177 
179 (
180  label partNumber,
181  const string& partDescription
182 )
183 :
184  ensightPart(partNumber, partDescription),
185  mesh_(*reinterpret_cast<polyMesh*>(0))
186 {}
187 
188 
190 (
191  label partNumber,
192  const polyMesh& mesh
193 )
194 :
195  ensightPart(partNumber, "cells", mesh.points()),
196  mesh_(mesh)
197 {
198  classify(mesh);
199 }
200 
201 
203 (
204  label partNumber,
205  const polyMesh& mesh,
206  const labelUList& idList
207 )
208 :
209  ensightPart(partNumber, "cells", mesh.points()),
210  mesh_(mesh)
211 {
212  classify(mesh, idList);
213 }
214 
215 
217 (
218  label partNumber,
219  const polyMesh& mesh,
220  const cellZone& cZone
221 )
222 :
223  ensightPart(partNumber, cZone.name(), mesh.points()),
224  mesh_(mesh)
225 {
226  classify(mesh, cZone);
227 }
228 
229 
231 :
232  ensightPart(part),
233  mesh_(part.mesh_)
234 {}
235 
236 
238 :
239  ensightPart(),
241 {
242  reconstruct(is);
243 }
244 
245 
246 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
247 
249 {}
250 
251 
252 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
253 
254 Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
255 {
256  localPoints ptList(points_);
257  labelList& usedPoints = ptList.list;
258  label nPoints = 0;
259 
260  forAll(elemLists_, typeI)
261  {
262  const labelUList& idList = elemLists_[typeI];
263 
264  // add all points from cells
265  forAll(idList, i)
266  {
267  const label id = idList[i] + offset_;
268  const labelUList& cFaces = mesh_.cells()[id];
269 
270  forAll(cFaces, cFacei)
271  {
272  const face& f = mesh_.faces()[cFaces[cFacei]];
273 
274  forAll(f, fp)
275  {
276  if (usedPoints[f[fp]] == -1)
277  {
278  usedPoints[f[fp]] = nPoints++;
279  }
280  }
281  }
282  }
283  }
284 
285  // this is not absolutely necessary, but renumber anyhow
286  nPoints = 0;
287  forAll(usedPoints, ptI)
288  {
289  if (usedPoints[ptI] > -1)
290  {
291  usedPoints[ptI] = nPoints++;
292  }
293  }
294 
295  ptList.nPoints = nPoints;
296  return ptList;
297 }
298 
299 
300 void Foam::ensightPartCells::writeConnectivity
301 (
302  ensightGeoFile& os,
303  const word& key,
304  const labelUList& idList,
305  const labelUList& pointMap
306 ) const
307 {
308  os.writeKeyword(key);
309  os.write(idList.size());
310  os.newline();
311 
312  // write polyhedral
313  if (key == "nfaced")
314  {
315  const faceList& meshFaces = mesh_.faces();
316  const labelUList& owner = mesh_.faceOwner();
317 
318  // write the number of faces per element
319  forAll(idList, i)
320  {
321  const label id = idList[i] + offset_;
322  const labelUList& cFace = mesh_.cells()[id];
323 
324  os.write(cFace.size());
325  os.newline();
326  }
327 
328  // write the number of points per element face
329  forAll(idList, i)
330  {
331  const label id = idList[i] + offset_;
332  const labelUList& cFace = mesh_.cells()[id];
333 
334  forAll(cFace, facei)
335  {
336  const face& cf = meshFaces[cFace[facei]];
337 
338  os.write(cf.size());
339  os.newline();
340  }
341  }
342 
343  // write the points describing each element face
344  forAll(idList, i)
345  {
346  const label id = idList[i] + offset_;
347  const labelUList& cFace = mesh_.cells()[id];
348 
349  forAll(cFace, cFacei)
350  {
351  const label faceId = cFace[cFacei];
352  const face& cf = meshFaces[faceId];
353 
354  // convert global -> local index
355  // (note: Ensight indices start with 1)
356 
357  // ensight >= 9 needs consistently oriented nfaced cells
358  if (id == owner[faceId])
359  {
360  forAll(cf, ptI)
361  {
362  os.write(pointMap[cf[ptI]] + 1);
363  }
364  }
365  else
366  {
367  // as per face::reverseFace(), but without copying
368 
369  os.write(pointMap[cf[0]] + 1);
370  for (label ptI = cf.size()-1; ptI > 0; --ptI)
371  {
372  os.write(pointMap[cf[ptI]] + 1);
373  }
374  }
375 
376  os.newline();
377  }
378  }
379  }
380  else
381  {
382  // write primitive
383  const cellShapeList& cellShapes = mesh_.cellShapes();
384 
385  forAll(idList, i)
386  {
387  const label id = idList[i] + offset_;
388  const cellShape& cellPoints = cellShapes[id];
389 
390  // convert global -> local index
391  // (note: Ensight indices start with 1)
392  forAll(cellPoints, ptI)
393  {
394  os.write(pointMap[cellPoints[ptI]] + 1);
395  }
396  os.newline();
397  }
398  }
399 }
400 
401 
403 {
405 }
406 
407 
408 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
label faceId(-1)
static const cellModel * lookup(const word &)
Look up a model by name and return a pointer to the model or NULL.
Definition: cellModeller.C:88
label nPoints
Number of points used.
Definition: ensightPart.H:109
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
Specialized Ensight output with extra geometry file header.
const pointField & points_
pointField referenced
Definition: ensightPart.H:99
Track the points used by the part and map global to local indices.
Definition: ensightPart.H:105
An implementation of ensightPart to hold volume mesh cells.
virtual void writeGeometry(ensightGeoFile &) const
Write geometry.
labelListList elemLists_
Simple labelList with a name.
Definition: ensightPart.H:84
const cellList & cells() const
labelList list
Map global to local indices.
Definition: ensightPart.H:112
Macros for easy insertion into run-time selection tables.
UList< label > labelUList
Definition: UList.H:64
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:979
const word & name() const
Return name.
Definition: zone.H:150
const cellShapeList & cellShapes() const
Return cell shapes.
List< cellShape > cellShapeList
List of cellShapes and PtrList of List of cellShape.
Definition: cellShapeList.H:43
A class for handling words, derived from string.
Definition: word.H:59
label nPoints
void reconstruct(Istream &)
Reconstruct part characteristics (eg, element types) from Istream.
List< label > labelList
A List of labels.
Definition: labelList.H:56
virtual Ostream & writeKeyword(const string &key)
Write keyword with trailing newline.
virtual Ostream & write(const char *buf, std::streamsize count)
Binary write.
Definition: ensightFile.C:136
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
Base class for ensightPartCells and ensightPartFaces.
Definition: ensightPart.H:65
defineTypeNameAndDebug(combustionModel, 0)
labelList f(nPoints)
A subset of mesh cells.
Definition: cellZone.H:61
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:46
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
void newline()
Add carriage return to ascii stream.
Definition: ensightFile.C:259
const Foam::edgeFaceCirculator Foam::edgeFaceCirculator::endConstIter * reinterpret_cast(0),-1, false,-1, false
label offset_
Start offset for elemLists_.
Definition: ensightPart.H:87
label cellId
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
static const List< word > elemTypes_
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1017
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1004
ensightPartCells(label partNumber, const string &partDescription)
Construct empty part with number and description.
virtual ~ensightPartCells()
Destructor.
const polyMesh & mesh_
Mesh referenced.
virtual void writeGeometry(ensightGeoFile &) const
Write geometry.
Definition: ensightPart.H:307
Namespace for OpenFOAM.