ensightFaces.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) 2016-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "ensightFaces.H"
29 #include "error.H"
30 #include "polyMesh.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(ensightFaces, 0);
37 }
38 
39 const char* Foam::ensightFaces::elemNames[3] =
40 {
41  "tria3", "quad4", "nsided"
42 };
43 
44 static_assert
45 (
47  "Support exactly 3 face types (tria3, quad4, nsided)"
48 );
49 
50 
51 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
52 
53 namespace
54 {
55 
56 // Trivial shape classifier
57 inline Foam::ensightFaces::elemType whatType(const Foam::face& f)
58 {
59  return
60  (
61  f.size() == 3
62  ? Foam::ensightFaces::elemType::TRIA3
63  : f.size() == 4
64  ? Foam::ensightFaces::elemType::QUAD4
65  : Foam::ensightFaces::elemType::NSIDED
66  );
67 }
68 
69 } // End anonymous namespace
70 
71 
72 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
73 
74 void Foam::ensightFaces::resizeAll()
75 {
76  // Invalidate any previous face ordering
77  faceOrder_.clear();
78 
79  // Invalidate any previous flipMap
80  flipMap_.clear();
81 
82  // Assign sub-list offsets, determine overall size
83 
84  label len = 0;
85 
86  auto iter = offsets_.begin();
87 
88  *iter = 0;
89  for (const label n : sizes_)
90  {
91  len += n;
92 
93  *(++iter) = len;
94  }
95 
96  // The addressing space
97  addressing().resize(len, Zero);
98 }
99 
100 
101 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
102 
104 :
105  ensightPart(),
106  faceOrder_(),
107  flipMap_(),
108  offsets_(Zero),
109  sizes_(Zero)
110 {}
111 
112 
113 Foam::ensightFaces::ensightFaces(const string& description)
114 :
115  ensightFaces()
116 {
117  rename(description);
118 }
119 
120 
121 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
122 
124 {
126 
127  for (int typei = 0; typei < nTypes; ++typei)
128  {
129  count[typei] = size(elemType(typei));
130  }
131 
132  return count;
133 }
134 
135 
136 Foam::label Foam::ensightFaces::totalSize() const noexcept
137 {
138  label count = 0;
139  for (label n : sizes_)
140  {
141  count += n;
142  }
143  return count;
144 }
145 
146 
148 {
149  clearOut();
150 
152 
153  faceOrder_.clear();
154  flipMap_.clear();
155  sizes_ = Zero;
156  offsets_ = Zero;
157 }
158 
159 
161 {}
162 
163 
165 {
166  for (int typei = 0; typei < nTypes; ++typei)
167  {
168  sizes_[typei] = size(elemType(typei));
169  }
170  Foam::reduce(sizes_, sumOp<label>());
171 }
172 
173 
175 {
176  // Some extra safety
177  if (faceOrder_.size() != size())
178  {
179  faceOrder_.clear();
180  }
181  if (flipMap_.size() != size())
182  {
183  flipMap_.clear();
184  }
185 
186  // Sort by face Ids.
187  // Use to reorder flip maps and face-order too.
188 
189  for (int typei=0; typei < nTypes; ++typei)
190  {
191  const labelRange sub(range(elemType(typei)));
192 
193  if (!sub.empty())
194  {
195  SubList<label> ids(sub, addressing());
196  labelList order(Foam::sortedOrder(ids));
197 
198  ids = reorder<labelList>(order, ids);
199 
200  // Sort flip map as well
201  if (!flipMap_.empty())
202  {
203  SubList<bool> flips(flipMap_, sub);
204  flips = reorder<boolList>(order, flips);
205  }
206 
207  // Sort face ordering as well
208  if (!faceOrder_.empty())
209  {
210  SubList<label> faceOrder(faceOrder_, sub);
211  faceOrder = reorder<labelList>(order, faceOrder);
212  }
213  }
214  }
215 }
216 
217 
218 void Foam::ensightFaces::classify(const UList<face>& faces)
219 {
220  const label len = faces.size();
221 
222  // Pass 1: Count the shapes
223 
224  sizes_ = Zero; // reset sizes
225  for (label listi = 0; listi < len; ++listi)
226  {
227  const auto etype = whatType(faces[listi]);
228 
229  ++sizes_[etype];
230  }
231 
232  resizeAll(); // adjust allocation
233  sizes_ = Zero; // reset sizes - use for local indexing here
234 
235  // Pass 2: Assign face-id per shape type
236 
237  for (label listi = 0; listi < len; ++listi)
238  {
239  const auto etype = whatType(faces[listi]);
241  add(etype, listi);
242  }
243 }
244 
245 
247 (
248  const UList<face>& faces,
249  const labelRange& range
250 )
251 {
252  const labelRange slice(range.subset0(faces.size()));
253 
254  // Operate on a local slice
255  classify(SubList<face>(slice, faces));
257  // Fixup to use the real faceIds instead of the 0-based slice
258  incrAddressing(slice.start());
259 }
260 
261 
263 (
264  const UList<face>& faces,
265  const labelUList& addr,
266  const boolList& flipMap,
267  const bitSet& exclude
268 )
269 {
270  const label len = addr.size();
271  const bool useFlip = (len == flipMap.size());
272 
273  // Pass 1: Count the shapes
274 
275  sizes_ = Zero; // reset sizes
276  for (label listi = 0; listi < len; ++listi)
277  {
278  const label faceId = addr[listi];
279 
280  if (!exclude.test(faceId))
281  {
282  const auto etype = whatType(faces[faceId]);
283 
284  ++sizes_[etype];
285  }
286  }
287 
288  resizeAll(); // adjust allocation
289  sizes_ = Zero; // reset sizes - use for local indexing here
290 
291  label nUsed = addressing().size();
292 
293  if (useFlip)
294  {
295  flipMap_.resize(nUsed);
296  flipMap_ = false;
297  }
298 
299  faceOrder_.resize(nUsed);
300 
301  // Pass 2: Assign face-id per shape type
302  // - also record the face order
303 
304  nUsed = 0;
305  for (label listi = 0; listi < len; ++listi)
306  {
307  const label faceId = addr[listi];
308 
309  if (!exclude.test(faceId))
310  {
311  const bool doFlip = useFlip && flipMap.test(listi);
312 
313  const auto etype = whatType(faces[faceId]);
314 
315  const label idx = add(etype, faceId, doFlip);
316 
317  faceOrder_[nUsed] = idx;
318  ++nUsed;
319  }
320  }
321 }
322 
323 
324 void Foam::ensightFaces::writeDict(Ostream& os, const bool full) const
325 {
326  os.beginBlock(type());
327 
328  os.writeEntry("id", index()+1); // Ensight starts with 1
329  os.writeEntry("name", name());
330  os.writeEntry("size", size());
331 
332  if (full)
333  {
334  for (int typei=0; typei < ensightFaces::nTypes; ++typei)
335  {
336  const auto etype = ensightFaces::elemType(typei);
337 
339 
340  faceIds(etype).writeList(os, 0) << endEntry; // Flat output
341  }
342  }
343 
344  os.endBlock();
345 }
346 
347 
348 // ************************************************************************* //
void clear()
Clear element addressing.
Definition: ensightPart.H:101
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
void clear()
Set addressable sizes to zero, free up addressing memory.
Definition: ensightFaces.C:140
label faceId(-1)
static const char * elemNames[nTypes]
The ensight &#39;Face&#39; element type names.
Definition: ensightFaces.H:94
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:107
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:160
iterator begin() noexcept
Return an iterator to begin traversing the FixedList.
Definition: FixedListI.H:482
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
FixedList< label, nTypes > sizes() const
Processor-local sizes per element type.
Definition: ensightFaces.C:116
Sorting/classification of faces (2D) into corresponding ensight types.
Definition: ensightFaces.H:66
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:321
Ostream & endEntry(Ostream &os)
Write end entry (&#39;;&#39;) followed by newline.
Definition: Ostream.H:565
void clearOut()
Clear any demand-driven data.
Definition: ensightFaces.C:153
scalar range
void reduce()
Sum element counts across all processes.
Definition: ensightFaces.C:157
label totalSize() const noexcept
The global size of all element types.
Definition: ensightFaces.C:129
void classify(const UList< face > &faces)
Classify the face types and set the element lists.
Definition: ensightFaces.C:211
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:137
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:108
ensightFaces()
Default construct, with part index 0.
Definition: ensightFaces.C:96
bool test(const label pos) const
Test for True value at specified position, never auto-vivify entries.
Definition: bitSet.H:326
const labelList & addressing() const noexcept
Element addressing.
Definition: ensightPart.H:85
const direction noexcept
Definition: Scalar.H:258
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Base class for ensightCells, ensightFaces, ensightOutputSurfaces.
Definition: ensightPart.H:49
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
static constexpr int nTypes
Number of &#39;Face&#39; element types (3)
Definition: ensightFaces.H:89
labelList f(nPoints)
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type test(const label i) const
Test bool value at specified position, always false for out-of-range access.
Definition: UList.H:769
static const char * key(const elemType etype) noexcept
The ensight element name for the specified &#39;Face&#39; type.
Definition: ensightFacesI.H:42
elemType
Supported ensight &#39;Face&#39; element types.
Definition: ensightFaces.H:79
void sort()
Inplace sort element lists numerically.
Definition: ensightFaces.C:167
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:90
label n
List< label > labelList
A List of labels.
Definition: List.H:62
virtual void writeDict(Ostream &os, const bool full=false) const
Write information about the object as a dictionary, optionally write all element addresses.
Definition: ensightFaces.C:317
Namespace for OpenFOAM.
virtual Ostream & writeKeyword(const keyType &kw)
Write the keyword followed by an appropriate indentation.
Definition: Ostream.C:60
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127