ensightPartCells.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 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 
41 const Foam::polyMesh* const Foam::ensightPartCells::polyMeshNullPtr_ = nullptr;
42 
44 (
45  IStringStream
46  (
47  "(tetra4 pyramid5 penta6 hexa8 nfaced)"
48  )()
49 );
50 
51 
52 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
53 
54 void Foam::ensightPartCells::classify
55 (
56  const polyMesh& mesh,
57  const labelUList& idList
58 )
59 {
60  // References to cell shape models
61  const cellModel& tet = *(cellModeller::lookup("tet"));
62  const cellModel& pyr = *(cellModeller::lookup("pyr"));
63  const cellModel& prism = *(cellModeller::lookup("prism"));
64  const cellModel& hex = *(cellModeller::lookup("hex"));
65 
66  const cellShapeList& cellShapes = mesh.cellShapes();
67 
68  offset_ = 0;
69  size_ = mesh.nCells();
70 
71  bool limited = false;
72  if (notNull(idList))
73  {
74  limited = true;
75  size_ = idList.size();
76  }
77 
78  // count the shapes
79  label nTet = 0;
80  label nPyr = 0;
81  label nPrism = 0;
82  label nHex = 0;
83  label nPoly = 0;
84 
85  for (label listI = 0; listI < size_; ++listI)
86  {
87  label cellId = listI;
88  if (limited)
89  {
90  cellId = idList[listI];
91  }
92 
93  const cellShape& cellShape = cellShapes[cellId];
94  const cellModel& cellModel = cellShape.model();
95 
96  if (cellModel == tet)
97  {
98  nTet++;
99  }
100  else if (cellModel == pyr)
101  {
102  nPyr++;
103  }
104  else if (cellModel == prism)
105  {
106  nPrism++;
107  }
108  else if (cellModel == hex)
109  {
110  nHex++;
111  }
112  else
113  {
114  nPoly++;
115  }
116  }
117 
118 
119  // we can avoid double looping, but at the cost of allocation
120  labelList tetCells(nTet);
121  labelList pyramidCells(nPyr);
122  labelList prismCells(nPrism);
123  labelList hexCells(nHex);
124  labelList polyCells(nPoly);
125 
126  nTet = 0,
127  nPyr = 0;
128  nPrism = 0;
129  nHex = 0;
130  nPoly = 0;
131 
132  // classify the shapes
133  for (label listI = 0; listI < size_; ++listI)
134  {
135  label cellId = listI;
136  if (limited)
137  {
138  cellId = idList[listI];
139  }
140 
141  const cellShape& cellShape = cellShapes[cellId];
142  const cellModel& cellModel = cellShape.model();
143 
144  if (cellModel == tet)
145  {
146  tetCells[nTet++] = cellId;
147  }
148  else if (cellModel == pyr)
149  {
150  pyramidCells[nPyr++] = cellId;
151  }
152  else if (cellModel == prism)
153  {
154  prismCells[nPrism++] = cellId;
155  }
156  else if (cellModel == hex)
157  {
158  hexCells[nHex++] = cellId;
159  }
160  else
161  {
162  polyCells[nPoly++] = cellId;
163  }
164  }
165 
166 
167  // MUST match with elementTypes
168  elemLists_.setSize(elementTypes().size());
169 
170  elemLists_[tetra4Elements].transfer(tetCells);
171  elemLists_[pyramid5Elements].transfer(pyramidCells);
172  elemLists_[penta6Elements].transfer(prismCells);
173  elemLists_[hexa8Elements].transfer(hexCells);
174  elemLists_[nfacedElements].transfer(polyCells);
175 }
176 
177 
178 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
179 
181 (
182  label partNumber,
183  const string& partDescription
184 )
185 :
186  ensightPart(partNumber, partDescription),
187  mesh_(*polyMeshNullPtr_)
188 {}
189 
190 
192 (
193  label partNumber,
194  const polyMesh& mesh
195 )
196 :
197  ensightPart(partNumber, "cells", mesh.points()),
198  mesh_(mesh)
199 {
200  classify(mesh);
201 }
202 
203 
205 (
206  label partNumber,
207  const polyMesh& mesh,
208  const labelUList& idList
209 )
210 :
211  ensightPart(partNumber, "cells", mesh.points()),
212  mesh_(mesh)
213 {
214  classify(mesh, idList);
215 }
216 
217 
219 (
220  label partNumber,
221  const polyMesh& mesh,
222  const cellZone& cZone
223 )
224 :
225  ensightPart(partNumber, cZone.name(), mesh.points()),
226  mesh_(mesh)
227 {
228  classify(mesh, cZone);
229 }
230 
231 
233 :
234  ensightPart(part),
235  mesh_(part.mesh_)
236 {}
237 
238 
240 :
241  ensightPart(),
243 {
244  reconstruct(is);
245 }
246 
247 
248 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
249 
251 {}
252 
253 
254 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
255 
256 Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
257 {
258  localPoints ptList(points_);
259  labelList& usedPoints = ptList.list;
260  label nPoints = 0;
261 
262  forAll(elemLists_, typeI)
263  {
264  const labelUList& idList = elemLists_[typeI];
265 
266  // add all points from cells
267  forAll(idList, i)
268  {
269  const label id = idList[i] + offset_;
270  const labelUList& cFaces = mesh_.cells()[id];
271 
272  forAll(cFaces, cFacei)
273  {
274  const face& f = mesh_.faces()[cFaces[cFacei]];
275 
276  forAll(f, fp)
277  {
278  if (usedPoints[f[fp]] == -1)
279  {
280  usedPoints[f[fp]] = nPoints++;
281  }
282  }
283  }
284  }
285  }
286 
287  // this is not absolutely necessary, but renumber anyhow
288  nPoints = 0;
289  forAll(usedPoints, ptI)
290  {
291  if (usedPoints[ptI] > -1)
292  {
293  usedPoints[ptI] = nPoints++;
294  }
295  }
296 
297  ptList.nPoints = nPoints;
298  return ptList;
299 }
300 
301 
302 void Foam::ensightPartCells::writeConnectivity
303 (
304  ensightGeoFile& os,
305  const word& key,
306  const labelUList& idList,
307  const labelUList& pointMap
308 ) const
309 {
310  os.writeKeyword(key);
311  os.write(idList.size());
312  os.newline();
313 
314  // write polyhedral
315  if (key == "nfaced")
316  {
317  const faceList& meshFaces = mesh_.faces();
318  const labelUList& owner = mesh_.faceOwner();
319 
320  // write the number of faces per element
321  forAll(idList, i)
322  {
323  const label id = idList[i] + offset_;
324  const labelUList& cFace = mesh_.cells()[id];
325 
326  os.write(cFace.size());
327  os.newline();
328  }
329 
330  // write the number of points per element face
331  forAll(idList, i)
332  {
333  const label id = idList[i] + offset_;
334  const labelUList& cFace = mesh_.cells()[id];
335 
336  forAll(cFace, facei)
337  {
338  const face& cf = meshFaces[cFace[facei]];
339 
340  os.write(cf.size());
341  os.newline();
342  }
343  }
344 
345  // write the points describing each element face
346  forAll(idList, i)
347  {
348  const label id = idList[i] + offset_;
349  const labelUList& cFace = mesh_.cells()[id];
350 
351  forAll(cFace, cFacei)
352  {
353  const label faceId = cFace[cFacei];
354  const face& cf = meshFaces[faceId];
355 
356  // convert global -> local index
357  // (note: Ensight indices start with 1)
358 
359  // ensight >= 9 needs consistently oriented nfaced cells
360  if (id == owner[faceId])
361  {
362  forAll(cf, ptI)
363  {
364  os.write(pointMap[cf[ptI]] + 1);
365  }
366  }
367  else
368  {
369  // as per face::reverseFace(), but without copying
370 
371  os.write(pointMap[cf[0]] + 1);
372  for (label ptI = cf.size()-1; ptI > 0; --ptI)
373  {
374  os.write(pointMap[cf[ptI]] + 1);
375  }
376  }
377 
378  os.newline();
379  }
380  }
381  }
382  else
383  {
384  // write primitive
385  const cellShapeList& cellShapes = mesh_.cellShapes();
386 
387  forAll(idList, i)
388  {
389  const label id = idList[i] + offset_;
390  const cellShape& cellPoints = cellShapes[id];
391 
392  // convert global -> local index
393  // (note: Ensight indices start with 1)
394  forAll(cellPoints, ptI)
395  {
396  os.write(pointMap[cellPoints[ptI]] + 1);
397  }
398  os.newline();
399  }
400  }
401 }
402 
403 
405 {
407 }
408 
409 
410 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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 nullptr.
Definition: cellModeller.C:100
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:164
const cellShapeList & cellShapes() const
Return cell shapes.
Specialised 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.
const cellList & cells() const
labelListList elemLists_
Simple labelList with a name.
Definition: ensightPart.H:84
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:65
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1131
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.
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1169
virtual void writeGeometry(ensightGeoFile &) const
Write geometry.
Definition: ensightPart.H:307
List< label > labelList
A List of labels.
Definition: labelList.H:56
const word & name() const
Return name.
Definition: zone.H:147
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1156
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:52
static const polyMesh *const polyMeshNullPtr_
void newline()
Add carriage return to ascii stream.
Definition: ensightFile.C:259
label offset_
Start offset for elemLists_.
Definition: ensightPart.H:87
label cellId
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
virtual void writeGeometry(ensightGeoFile &) const
Write geometry.
static const List< word > elemTypes_
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
ensightPartCells(label partNumber, const string &partDescription)
Construct empty part with number and description.
virtual ~ensightPartCells()
Destructor.
const polyMesh & mesh_
Mesh referenced.
Namespace for OpenFOAM.