ensightMesh.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "ensightMesh.H"
30 #include "ensightGeoFile.H"
31 #include "polyMesh.H"
32 #include "emptyPolyPatch.H"
33 #include "processorPolyPatch.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 const Foam::label Foam::ensightMesh::internalZone = -1;
38 
39 
40 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44 
45 // Patch names without processor patches
47 {
48  #ifdef FULLDEBUG
49  // Patches are output. Check that they are synced.
50  bmesh.checkParallelSync(true);
51  #endif
52 
53  wordList patchNames(bmesh.names());
55 
56  return patchNames;
57 }
58 
59 
60 } // End namespace Foam
61 
62 
63 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
64 
65 void Foam::ensightMesh::clear()
66 {
67  cellZoneParts_.clear();
68  faceZoneParts_.clear();
69  boundaryParts_.clear();
70 }
71 
72 
73 void Foam::ensightMesh::renumber()
74 {
75  label partNo = 0;
76 
77  for (const label id : cellZoneParts_.sortedToc())
78  {
79  cellZoneParts_[id].index() = partNo++;
80  }
81 
82  for (const label id : boundaryParts_.sortedToc())
83  {
84  boundaryParts_[id].index() = partNo++;
85  }
86 
87  for (const label id : faceZoneParts_.sortedToc())
88  {
89  faceZoneParts_[id].index() = partNo++;
90  }
91 }
92 
93 
94 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
95 
96 Foam::ensightMesh::ensightMesh
97 (
98  const polyMesh& mesh
99 )
100 :
102 {}
103 
104 
105 Foam::ensightMesh::ensightMesh
106 (
107  const polyMesh& mesh,
108  const ensightMesh::options& opts
109 )
110 :
111  options_(new options(opts)),
112  mesh_(mesh),
113  needsUpdate_(true)
114 {
115  if (!option().lazy())
116  {
117  correct();
118  }
119 }
120 
121 
122 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
123 
125 {
126  clear();
127 
128  const wordRes& czMatcher = option().cellZoneSelection();
129  const wordRes& fzMatcher = option().faceZoneSelection();
130 
131  // Possible cellZones
132  const wordList czNames =
133  (
134  (
135  option().useCellZones()
136  && (!czMatcher.empty() || option().useInternalMesh())
137  )
138  ? mesh_.cellZones().names()
139  : wordList()
140  );
141 
142  const labelList czoneIds =
143  (
144  czMatcher.empty()
145  ? identity(czNames.size()) // All
146  : czMatcher.matching(czNames) // Selected names
147  );
148 
149 
150  // Possible faceZones
151  const wordList fzNames =
152  (
153  option().useFaceZones()
154  ? mesh_.faceZones().names()
155  : wordList()
156  );
157 
158  const labelList fzoneIds =
159  (
160  fzMatcher.empty()
161  ? identity(fzNames.size()) // All
162  : fzMatcher.matching(fzNames) // Selected names
163  );
164 
165 
166  // Possible patchNames
167  const wordList patchNames =
168  (
169  option().useBoundaryMesh()
170  ? nonProcessorPatchNames(mesh_.boundaryMesh())
171  : wordList()
172  );
173 
174  const labelList patchIds =
175  (
176  option().useBoundaryMesh()
178  (
179  patchNames,
180  option().patchSelection(),
181  option().patchExclude()
182  )
183  : labelList()
184  );
185 
186 
187  // Track which cells are in a zone or not
188  bitSet cellSelection;
189 
190  // Faces to be excluded from export
191  bitSet excludeFace;
192 
193 
194  // cellZones first
195  for (const label zoneId : czoneIds)
196  {
197  const word& zoneName = czNames[zoneId];
198  const cellZone& zn = mesh_.cellZones()[zoneId];
199 
200  if (returnReduce(!zn.empty(), orOp<bool>()))
201  {
202  cellSelection.set(zn);
203 
204  ensightCells& part = cellZoneParts_(zoneId);
205 
206  part.clear();
207  part.identifier() = zoneId;
208  part.rename(zoneName);
209 
210  part.classify(mesh_, zn);
211 
212  // Finalize
213  part.reduce();
214  }
215  }
216 
217  if (option().useInternalMesh() && czMatcher.empty())
218  {
219  // The internal mesh:
220  // Either the entire mesh (if no zones specified)
221  // or whatever is leftover as unzoned
222 
223  if (cellZoneParts_.empty())
224  {
225  ensightCells& part = cellZoneParts_(internalZone);
226 
227  part.clear();
228  part.identifier() = internalZone;
229  part.rename("internalMesh");
230 
231  part.classify(mesh_);
232 
233  // Finalize
234  part.reduce();
235  }
236  else
237  {
238  // Unzoned cells - flip selection from zoned to unzoned
239  cellSelection.flip();
240 
241  if (returnReduce(cellSelection.any(), orOp<bool>()))
242  {
243  ensightCells& part = cellZoneParts_(internalZone);
244 
245  part.clear();
246  part.identifier() = internalZone;
247  part.rename("internalMesh");
248 
249  part.classify(mesh_, cellSelection);
250 
251  // Finalize
252  part.reduce();
253  }
254  }
255 
256  // Handled all cells
257  cellSelection.clearStorage();
258  }
259  else if (cellSelection.none())
260  {
261  // No internal, no cellZones selected - just ignore
262  cellSelection.clearStorage();
263  }
264 
265 
266  // Face exclusion based on cellZones
267 
268  if (returnReduce(!cellSelection.empty(), orOp<bool>()))
269  {
270  excludeFace.resize(mesh_.nFaces());
271 
272  const labelList& owner = mesh_.faceOwner();
273 
274  forAll(owner, facei)
275  {
276  const label celli = owner[facei];
277 
278  if (!cellSelection.test(celli))
279  {
280  excludeFace.set(facei);
281  }
282  }
283  }
284 
285 
286  // Face exclusion for empty/processor types
287  // so they are ignored for face zones
288 
289  if (fzoneIds.size())
290  {
291  excludeFace.resize(mesh_.nFaces());
292 
293  for (const polyPatch& p : mesh_.boundaryMesh())
294  {
295  const auto* procPatch = isA<processorPolyPatch>(p);
296 
297  if (isA<emptyPolyPatch>(p))
298  {
299  excludeFace.set(p.range());
300  }
301  else if (procPatch && !procPatch->owner())
302  {
303  // Exclude neighbour-side, retain owner-side only
304  excludeFace.set(p.range());
305  }
306  }
307  }
308 
309 
310  // Patches
311  for (const label patchId : patchIds)
312  {
313  const word& patchName = patchNames[patchId];
314  const polyPatch& p = mesh_.boundaryMesh()[patchId];
315 
316  if (isA<emptyPolyPatch>(p))
317  {
318  // Skip empty patch types
319  continue;
320  }
321  else if (isA<processorPolyPatch>(p))
322  {
323  // Only real (non-processor) boundaries.
324  break;
325  }
326 
327  ensightFaces& part = boundaryParts_(patchId);
328 
329  part.clear();
330  part.identifier() = patchId;
331  part.rename(patchName);
332 
333  part.classify
334  (
335  mesh_.faces(),
336  identity(p.range()),
337  boolList(), // no flip map
338  excludeFace
339  );
340 
341  // Finalize
342  part.reduce();
343 
344  if (!part.total())
345  {
346  boundaryParts_.erase(patchId);
347  }
348  }
349 
350 
351  // Face zones
352 
353  for (const label zoneId : fzoneIds)
354  {
355  const word& zoneName = fzNames[zoneId];
356  const faceZone& zn = mesh_.faceZones()[zoneId];
357 
358  ensightFaces& part = faceZoneParts_(zoneId);
359 
360  part.clear();
361  part.identifier() = zoneId;
362  part.rename(zoneName);
363 
364  if (zn.size())
365  {
366  part.classify
367  (
368  mesh_.faces(),
369  zn,
370  zn.flipMap(),
371  excludeFace
372  );
373  }
374 
375  // Finalize
376  part.reduce();
377 
378  if (!part.total())
379  {
380  faceZoneParts_.erase(zoneId);
381  }
382  }
383 
384  renumber();
385 
386  needsUpdate_ = false;
387 }
388 
389 
391 (
392  ensightGeoFile& os,
393  bool parallel
394 ) const
395 {
396  // The internalMesh, cellZones
397  for (const label id : cellZoneParts_.sortedToc())
398  {
399  cellZoneParts_[id].write(os, mesh_, parallel);
400  }
401 
402  // Patches - sorted by index
403  for (const label id : boundaryParts_.sortedToc())
404  {
405  boundaryParts_[id].write(os, mesh_, parallel);
406  }
407 
408  // Requested faceZones - sorted by index
409  for (const label id : faceZoneParts_.sortedToc())
410  {
411  faceZoneParts_[id].write(os, mesh_, parallel);
412  }
413 }
414 
415 
416 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::wordRes::matching
labelList matching(const UList< StringType > &input, const bool invert=false) const
Extract list indices for all matches.
Foam::ensightMesh
Encapsulation of volume meshes for writing in ensight format. It manages cellZones,...
Definition: ensightMesh.H:82
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
Foam::ensightPart::rename
void rename(const string &value)
Change the part name or description.
Definition: ensightPart.H:166
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
Foam::ensightMesh::correct
void correct()
Update for new mesh.
Definition: ensightMesh.C:124
Foam::bitSet::any
bool any() const
True if any bits in this bitset are set.
Definition: bitSetI.H:468
Foam::bitSet::set
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:574
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:69
Foam::PackedList::empty
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition: PackedListI.H:384
Foam::bitSet::test
bool test(const label pos) const
Test value at specified position, never auto-vivify entries.
Definition: bitSetI.H:520
polyMesh.H
Foam::PackedList::resize
void resize(const label nElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
Definition: PackedListI.H:399
Foam::ensightMesh::write
void write(autoPtr< ensightGeoFile > &os, bool parallel=Pstream::parRun()) const
Write geometry to file. Normally in parallel.
Definition: ensightMeshI.H:107
Foam::ensightFaces
Sorting/classification of faces (2D) into corresponding ensight types.
Definition: ensightFaces.H:68
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::polyBoundaryMesh::names
wordList names() const
Return a list of patch names.
Definition: polyBoundaryMesh.C:593
Foam::ensightMesh::internalZone
static const label internalZone
The zone-id for internal mesh or unzoned cells.
Definition: ensightMesh.H:87
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::cellZone
A subset of mesh cells.
Definition: cellZone.H:62
Foam::ensightFaces::total
label total() const
The global size of all element types.
Definition: ensightFaces.C:130
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:59
Foam::ensightGeoFile
Specialized Ensight output with extra geometry file header.
Definition: ensightGeoFile.H:48
Foam::polyBoundaryMesh::checkParallelSync
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order. Return.
Definition: polyBoundaryMesh.C:955
ensightMesh.H
Foam::ensightPart::identifier
label identifier() const
OpenFOAM identifier (patch, zone, etc), -1 when not in use.
Definition: ensightPart.H:136
patchIds
labelList patchIds
Definition: convertProcessorPatches.H:67
Foam::faceZone
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:65
Foam::ensightFaces::reduce
void reduce()
Sum element counts across all processes.
Definition: ensightFaces.C:157
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
correct
fvOptions correct(rho)
patchNames
wordList patchNames(nPatches)
Foam::stringListOps::findMatching
labelList findMatching(const StringListType &input, const wordRes &allow, const wordRes &deny=wordRes(), AccessOp aop=noOp())
Return ids for items with matching names.
Foam::ensightCells
Sorting/classification of cells (3D) into corresponding ensight element types.
Definition: ensightCells.H:54
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::bitSet::flip
void flip()
Invert all bits in the addressable region.
Definition: bitSetI.H:618
processorPolyPatch.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
emptyPolyPatch.H
Foam::polyBoundaryMesh::nNonProcessor
label nNonProcessor() const
The number of patches before the first processor patch.
Definition: polyBoundaryMesh.C:573
Foam::bitSet::none
bool none() const
True if no bits in this bitset are set.
Definition: bitSetI.H:487
Foam::renumber
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:37
ensightGeoFile.H
clear
patchWriters clear()
Foam::ensightMesh::options
Configuration options for the ensightMesh.
Definition: ensightMesh.H:213
Foam::List< word >
Foam::ensightFaces::clear
void clear()
Set addressable sizes to zero, free up addressing memory.
Definition: ensightFaces.C:141
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
Foam::PackedList::clearStorage
void clearStorage()
Clear the list and delete storage.
Definition: PackedListI.H:510
patchId
label patchId(-1)
Foam::ensightCells::classify
void classify(const polyMesh &mesh)
Classify cell types and set the element lists.
Definition: ensightCells.C:236
Foam::orOp
Definition: ops.H:234
Foam::faceZone::flipMap
const boolList & flipMap() const
Return face flip map.
Definition: faceZone.H:271
Foam::ensightCells::reduce
void reduce()
Sum element counts across all processes.
Definition: ensightCells.C:133
Foam::ensightCells::clear
void clear()
Set addressable sizes to zero, free up addressing memory.
Definition: ensightCells.C:118
Foam::ensightFaces::classify
void classify(const UList< face > &faces)
Classify the face types and set the element lists.
Definition: ensightFaces.C:212
Foam::nonProcessorPatchNames
static wordList nonProcessorPatchNames(const polyBoundaryMesh &bmesh)
Definition: ensightMesh.C:46