NASsurfaceFormat.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-2015 OpenFOAM Foundation
9  Copyright (C) 2017-2024 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 Notes (Reader)
28 
29  Nastran does not directly support any names, but ANSA and Hypermesh
30  have different ways to get around that problem by using/misusing
31  comment lines.
32 
33 Hypermesh extension (last verified approx. 2010)
34 
35  $HMNAME COMP 1"some-part-name"
36 
37 ANSA extension (legacy)
38 
39  line 1: $ANSA_NAME;<int>;<word>;
40  line 2: $some-part-name
41 
42 ANSA extension (19.0.1)
43 
44  line 1: $ANSA_NAME;<int>;PSHELL;~
45  line 2: $some-part-name
46 
47  These seem to appear immediately before the corrsponding PSHELL
48 
49 ANSA extension (23.1.0)
50 
51  $ANSA_NAME_COMMENT;<int>;PSHELL;some-part-name;; ...something trailing...
52 
53  These seem to appear as footer data, but could presumably appear anywhere.
54 
55 Random extension (not sure where this arises)
56 
57  $some-part-name
58  PSHELL 203101 1
59 
60  These seemingly random comments appear immediately before the PSHELL entry.
61 
62 \*---------------------------------------------------------------------------*/
63 
64 #include "NASsurfaceFormat.H"
65 #include "ListOps.H"
66 #include "Fstream.H"
67 #include "IOmanip.H"
68 #include "faceTraits.H"
69 #include "stringOps.H"
70 
71 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
72 
73 template<class Face>
75 (
76  Ostream& os,
77  const Face& f,
78  label elemId,
79  const label groupId
80 )
81 {
82  const label n = f.size();
83 
84  if (n == 3)
85  {
86  os << "CTRIA3" << ','
87  << (++elemId) << ','
88  << (groupId + 1) << ','
89  << (f[0] + 1) << ','
90  << (f[1] + 1) << ','
91  << (f[2] + 1) << nl;
92  }
93  else if (n == 4)
94  {
95  os << "CQUAD4" << ','
96  << (++elemId) << ','
97  << (groupId + 1) << ','
98  << (f[0] + 1) << ','
99  << (f[1] + 1) << ','
100  << (f[2] + 1) << ','
101  << (f[3] + 1) << nl;
102  }
103  else
104  {
105  // simple triangulation about f[0].
106  // better triangulation should have been done before
107  for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
108  {
109  const label fp2 = f.fcIndex(fp1);
110 
111  os << "CTRIA3" << ','
112  << (++elemId) << ','
113  << (groupId + 1) << ','
114  << (f[0] + 1) << ','
115  << (f[fp1] + 1) << ','
116  << (f[fp2] + 1) << nl;
117  }
118  }
119 
120  return elemId;
121 }
122 
123 
124 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
125 
126 template<class Face>
128 (
129  const fileName& filename
130 )
131 {
132  read(filename);
133 }
134 
135 
136 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
137 
138 template<class Face>
140 (
141  const fileName& filename
142 )
143 {
144  // Clear everything
145  this->clear();
146 
147  IFstream is(filename);
148  if (!is.good())
149  {
151  << "Cannot read file " << filename << nl
152  << exit(FatalError);
153  }
154 
155  DynamicList<label> pointId; // Nastran point id (1-based)
156  DynamicList<point> dynPoints;
157 
158  DynamicList<label> dynElemId; // Nastran element id (1-based)
159  DynamicList<Face> dynFaces;
160  DynamicList<label> dynZones;
161  DynamicList<label> dynSizes;
162 
163  Map<label> zoneLookup;
164 
165  // Assume that the groups are not intermixed
166  label zoneId = 0;
167  bool sorted = true;
168 
169  // Element id gets trashed with decompose into a triangle!
170  bool ignoreElemId = false;
171 
172  // Name for face group (limited to PSHELL)
173  Map<word> nameLookup;
174 
175  // A single warning per unrecognized command
176  wordHashSet unhandledCmd;
177 
178  // The line to parse
179  string line;
180 
181  // The last comment line seen (immediately before a 'real' command)
182  string lastComment;
183 
184  while (is.good())
185  {
186  // Parsing position within current line
187  std::string::size_type linei = 0;
188  is.getLine(line);
189 
190  if (NASCore::debug > 1) Info<< "Process: " << line << nl;
191 
192  // ANSA extension(s)
193  if (line.starts_with("$ANSA_NAME"))
194  {
195  // Keep empty elements when splitting
196  const auto args =
197  stringOps::split<std::string>(line, ';', 0, true);
198 
199  if (args.size() > 4 && line.starts_with("$ANSA_NAME_COMMENT"))
200  {
201  // This type of content
202  // $ANSA_NAME_COMMENT;93000;PSHELL;SLIP;;NO;NO;NO;NO;
203 
204  label groupId = 0;
205 
206  if (readLabel(args[1], groupId) && (args[2] == "PSHELL"))
207  {
208  word groupName = word::validate(args[3]);
209 
210  if (!groupName.empty())
211  {
212  DebugInfo
213  << "PSHELL:" << groupId
214  << " = " << groupName << nl;
215 
216  nameLookup.emplace(groupId, std::move(groupName));
217  }
218  }
219 
220  // Handled (or ignored)
221  continue;
222  }
223  else if (args.size() >= 3 && (args[0] == "$ANSA_NAME"))
224  {
225  // This type of content
226 
227  // line 1: $ANSA_NAME;<int>;PSHELL;~
228  // line 2: $some-part-name
229 
230  label groupId = 0;
231 
232  if (readLabel(args[1], groupId) && (args[2] == "PSHELL"))
233  {
234  // Fetch the next line
235  is.getLine(line);
236  line.removeEnd('\r'); // Possible CR-NL
237 
238  word groupName;
239  if (line.starts_with('$'))
240  {
241  groupName = word::validate(line.substr(1));
242  }
243 
244  if (!groupName.empty())
245  {
246  DebugInfo
247  << "PSHELL:" << groupId
248  << " = " << groupName << nl;
249 
250  nameLookup.emplace(groupId, std::move(groupName));
251  }
252  }
253  }
254 
255  // Drop through in case the second line read was not a comment !
256  }
257  else if (line.starts_with("$HMNAME COMP"))
258  {
259  // HYPERMESH extension
260  // This type of content
261  // $HMNAME COMP 1"partName"
262  // [NB: first entry is fixed record length of 32]
263 
264  auto dquote = line.find('"', 12); // Beyond '$HMNAME COMP'
265 
266  label groupId = 0;
267 
268  if
269  (
270  dquote != std::string::npos
271  && readLabel(line.substr(12, (dquote - 12)), groupId)
272  )
273  {
274  // word::validate automatically removes quotes too
275  word groupName = word::validate(line.substr(dquote));
276 
277  if (!groupName.empty())
278  {
279  DebugInfo
280  << "HMNAME group " << groupId
281  << " => " << groupName << nl;
282 
283  nameLookup.emplace(groupId, std::move(groupName));
284  }
285  }
286 
287  continue; // Handled
288  }
289 
290  if (line.empty())
291  {
292  continue; // Ignore empty
293  }
294  else if (line[0] == '$')
295  {
296  // Retain comment (see notes above about weird formats...)
297  lastComment = line;
298  continue;
299  }
300 
301  // Check if character 72 is continuation
302  if (line.size() > 72 && line[72] == '+')
303  {
304  line.resize(72);
305 
306  while (true)
307  {
308  string buf;
309  is.getLine(buf);
310 
311  if (buf.size() > 72 && buf[72] == '+')
312  {
313  line += buf.substr(8, 64);
314  }
315  else
316  {
317  line += buf.substr(8);
318  break;
319  }
320  }
321  }
322 
323  // First word (column 0-8)
324  const word cmd(word::validate(nextNasField(line, linei, 8)));
325 
326  if (cmd == "CTRIA3")
327  {
328  label elemId = readLabel(nextNasField(line, linei, 8)); // 8-16
329  label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24
330  const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32
331  const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40
332  const auto c = readLabel(nextNasField(line, linei, 8)); // 40-48
333 
334  // Convert groupId into zoneId
335  const auto iterZone = zoneLookup.cfind(groupId);
336  if (iterZone.good())
337  {
338  if (zoneId != iterZone.val())
339  {
340  // PSHELL types are intermixed
341  sorted = false;
342  }
343  zoneId = iterZone.val();
344  }
345  else
346  {
347  zoneId = dynSizes.size();
348  zoneLookup.insert(groupId, zoneId);
349  dynSizes.push_back(0);
350  // Info<< "zone" << zoneId << " => group " << groupId <<nl;
351  }
352 
353  --elemId; // Convert 1-based -> 0-based
354  dynElemId.push_back(elemId);
355  dynFaces.push_back(Face{a, b, c});
356  dynZones.push_back(zoneId);
357  dynSizes[zoneId]++;
358  }
359  else if (cmd == "CQUAD4")
360  {
361  label elemId = readLabel(nextNasField(line, linei, 8)); // 8-16
362  label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24
363  const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32
364  const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40
365  const auto c = readLabel(nextNasField(line, linei, 8)); // 40-48
366  const auto d = readLabel(nextNasField(line, linei, 8)); // 48-56
367 
368  // Convert groupId into zoneId
369  const auto iterZone = zoneLookup.cfind(groupId);
370  if (iterZone.good())
371  {
372  if (zoneId != iterZone.val())
373  {
374  // PSHELL types are intermixed
375  sorted = false;
376  }
377  zoneId = iterZone.val();
378  }
379  else
380  {
381  zoneId = dynSizes.size();
382  zoneLookup.insert(groupId, zoneId);
383  dynSizes.push_back(0);
384  // Info<< "zone" << zoneId << " => group " << groupId <<nl;
385  }
386 
387  if (faceTraits<Face>::isTri())
388  {
389  ignoreElemId = true;
390  dynElemId.clear();
391 
392  dynFaces.push_back(Face{a, b, c});
393  dynFaces.push_back(Face{c, d, a});
394  dynZones.push_back(zoneId);
395  dynZones.push_back(zoneId);
396  dynSizes[zoneId] += 2;
397  }
398  else
399  {
400  --elemId; // Convert 1-based -> 0-based
401 
402  dynElemId.push_back(elemId);
403  dynFaces.push_back(Face{a,b,c,d});
404  dynZones.push_back(zoneId);
405  dynSizes[zoneId]++;
406  }
407  }
408  else if (cmd == "GRID")
409  {
410  label index = readLabel(nextNasField(line, linei, 8)); // 8-16
411  (void) nextNasField(line, linei, 8); // 16-24
412  scalar x = readNasScalar(nextNasField(line, linei, 8)); // 24-32
413  scalar y = readNasScalar(nextNasField(line, linei, 8)); // 32-40
414  scalar z = readNasScalar(nextNasField(line, linei, 8)); // 40-48
415 
416  pointId.push_back(index);
417  dynPoints.emplace_back(x, y, z);
418  }
419  else if (cmd == "GRID*")
420  {
421  // Long format is on two lines with '*' continuation symbol
422  // on start of second line.
423  // Typical line (spaces compacted)
424  // GRID* 126 0 -5.55999875E+02 -5.68730474E+02
425  // * 2.14897901E+02
426 
427  label index = readLabel(nextNasField(line, linei, 16)); // 8-24
428  (void) nextNasField(line, linei, 16); // 24-40
429  scalar x = readNasScalar(nextNasField(line, linei, 16)); // 40-56
430  scalar y = readNasScalar(nextNasField(line, linei, 16)); // 56-72
431 
432  linei = 0; // restart at index 0
433  is.getLine(line);
434  if (line[0] != '*')
435  {
437  << "Expected continuation symbol '*' when reading GRID*"
438  << " (double precision coordinate) format" << nl
439  << "Read:" << line << nl
440  << "File:" << is.name() << " line:" << is.lineNumber()
441  << exit(FatalError);
442  }
443  (void) nextNasField(line, linei, 8); // 0-8
444  scalar z = readNasScalar(nextNasField(line, linei, 16)); // 8-16
445 
446  pointId.push_back(index);
447  dynPoints.emplace_back(x, y, z);
448  }
449  else if (cmd == "PSHELL")
450  {
451  // The last ditch effort to map PSHELL id to a group name.
452  // If ANSA or HMNAME didn't work, it is still possible to
453  // have the 'weird' format where the immediately preceeding
454  // comment contains the information.
455 
456  label groupId = readLabel(nextNasField(line, linei, 8)); // 8-16
457 
458  if (lastComment.size() > 1 && !nameLookup.contains(groupId))
459  {
460  word groupName = word::validate(lastComment.substr(1));
461 
462  if (!groupName.empty())
463  {
464  DebugInfo
465  << "PSHELL:" << groupId
466  << " = " << groupName << nl;
467 
468  nameLookup.emplace(groupId, std::move(groupName));
469  }
470  }
471  }
472  else if (unhandledCmd.insert(cmd))
473  {
474  InfoErr
475  << "Unhandled Nastran command " << line << nl
476  << "File:" << is.name() << " line:" << is.lineNumber()
477  << nl;
478  }
479 
480  // Discard buffered comment (from weird format...)
481  lastComment.clear();
482  }
483 
484 
485  // Info<< "Read faces:" << dynFaces.size()
486  // << " points:" << dynPoints.size()
487  // << endl;
488 
489  if (ignoreElemId)
490  {
491  dynElemId.clear();
492  }
493 
494  // Transfer to normal lists
495  this->storedPoints().transfer(dynPoints);
496 
497  dynFaces.shrink();
498 
499  // Build inverse mapping (NASTRAN pointId -> index)
500  Map<label> mapPointId(invertToMap(pointId));
501  pointId.clearStorage();
502 
503  // Relabel faces
504  // ~~~~~~~~~~~~~
505  for (Face& f : dynFaces)
506  {
507  for (label& vert : f)
508  {
509  vert = mapPointId[vert];
510  }
511  }
512  mapPointId.clear();
513 
514  DebugInfo
515  << "PSHELL names:" << nameLookup << nl;
516 
517  // Create default zone names, or from ANSA/Hypermesh information
518  List<word> names(dynSizes.size());
519  forAllConstIters(zoneLookup, iter)
520  {
521  const label groupId = iter.key();
522  const label zoneId = iter.val();
523 
524  const auto iterName = nameLookup.cfind(groupId);
525  if (iterName.good())
526  {
527  names[zoneId] = iterName.val();
528  }
529  else
530  {
531  names[zoneId] = surfZone::defaultName(zoneId);
532  }
533  }
534 
535  this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
536 
537  // Add zones (retaining empty ones)
538  this->addZones(dynSizes, names);
539  this->addZonesToFaces(); // for labelledTri
541  return true;
542 }
543 
544 
545 template<class Face>
547 (
548  const fileName& filename,
549  const MeshedSurfaceProxy<Face>& surf,
550  IOstreamOption streamOpt,
551  const dictionary&
552 )
553 {
554  // ASCII only, allow output compression
555  streamOpt.format(IOstreamOption::ASCII);
556 
557  const UList<point>& pointLst = surf.points();
558  const UList<Face>& faceLst = surf.surfFaces();
559  const UList<label>& faceMap = surf.faceMap();
560  const UList<label>& elemIds = surf.faceIds();
561 
562  // for no zones, suppress the group name
563  const surfZoneList zones =
564  (
565  surf.surfZones().empty()
566  ? surfaceFormatsCore::oneZone(faceLst, "")
567  : surf.surfZones()
568  );
569 
570  const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
571 
572  // Possible to use faceIds?
573  // - cannot if there are negative ids (eg, encoded solid/side)
574  bool useOrigFaceIds =
575  (
576  !useFaceMap
577  && elemIds.size() == faceLst.size()
578  && !ListOps::found(elemIds, lessOp1<label>(0))
579  );
580 
581  // Not possible with on-the-fly face decomposition
582  if (useOrigFaceIds)
583  {
584  for (const auto& f : faceLst)
585  {
586  if (f.size() > 4)
587  {
588  useOrigFaceIds = false;
589  break;
590  }
591  }
592  }
593 
594 
595  OFstream os(filename, streamOpt);
596  if (!os.good())
597  {
599  << "Cannot write file " << filename << nl
600  << exit(FatalError);
601  }
602 
603  // For simplicity, use fieldFormat::FREE throughout
604  fileFormats::NASCore::setPrecision(os, fieldFormat::FREE);
605 
606  os << "CEND" << nl
607  << "TITLE = " << os.name().stem() << nl;
608 
609  // Print zone names as comment
610  forAll(zones, zonei)
611  {
612  // HYPERMESH extension
613  os << "$HMNAME COMP" << setw(20) << (zonei+1)
614  << '"' << zones[zonei].name() << '"' << nl;
615  }
616 
617  // Write vertex coords with 1-based point Id
618  os << "$ GRID POINTS" << nl
619  << "BEGIN BULK" << nl;
620 
621  label pointId = 0;
622  for (const point& pt : pointLst)
623  {
624  os << "GRID" << ','
625  << ++pointId << ','
626  << 0 << ',' // global coordinate system
627  << pt.x() << ',' << pt.y() << ',' << pt.z() << nl;
628  }
629 
630  os << "$ ELEMENTS" << nl;
631 
632  label faceIndex = 0;
633  label zoneIndex = 0;
634  label elemId = 0;
635 
636  for (const surfZone& zone : zones)
637  {
638  for (label nLocal = zone.size(); nLocal--; ++faceIndex)
639  {
640  const label facei =
641  (useFaceMap ? faceMap[faceIndex] : faceIndex);
642 
643  const Face& f = faceLst[facei];
644 
645  if (useOrigFaceIds)
646  {
647  elemId = elemIds[facei];
648  }
649 
650  elemId = writeShell(os, f, elemId, zoneIndex);
651  }
652 
653  ++zoneIndex;
654  }
655 
656  os << "ENDDATA" << nl;
657 }
658 
659 
660 // ************************************************************************* //
reference val() const
Const access to referenced object (value)
Definition: HashTable.H:1201
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
A line primitive.
Definition: line.H:52
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
A class for handling file names.
Definition: fileName.H:72
bool emplace(const label &key, Args &&... args)
Emplace insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:129
Nastran surface reader/writer.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
messageStream InfoErr
Information stream (stderr output on master, null elsewhere)
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
Output to file stream as an OSstream, normally using std::ofstream for the actual output...
Definition: OFstream.H:71
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:63
A simple container for options an IOstream can normally have.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:232
const pointField & points() const noexcept
Return const access to the points.
const labelUList & faceMap() const noexcept
Const access to the faceMap, zero-sized when unused.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
static void write(const fileName &filename, const MeshedSurfaceProxy< Face > &surf, IOstreamOption streamOpt=IOstreamOption(), const dictionary &=dictionary::null)
Write surface mesh components (by proxy) in NAS format.
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
StringType validate(const std::string &str, const UnaryPredicate &accept, const bool invert=false)
Return a copy of the input string with validated characters.
NASsurfaceFormat(const fileName &filename)
Construct from file name.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:152
scalar y
virtual const fileName & name() const override
Read/write access to the name of the stream.
Definition: ISstream.H:147
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
bool contains(const label &key) const
True if hashed key is contained (found) in table.
Definition: HashTableI.H:72
bool useFaceMap() const noexcept
Can/should use faceMap?
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:113
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
A class for handling words, derived from Foam::string.
Definition: word.H:63
T & emplace_back(Args &&... args)
Construct an element at the end of the list, return reference to the new list element.
Definition: DynamicListI.H:538
const UList< surfZone > & surfZones() const noexcept
Const access to the surface zones.
label size() const noexcept
The number of arguments.
Definition: argListI.H:139
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:67
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:105
#define DebugInfo
Report an information message using Foam::Info.
Istream and Ostream manipulators taking arguments.
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:69
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
int debug
Static debugging option.
DynamicList< T, SizeMin > & shrink()
Calls shrink_to_fit() and returns a reference to the DynamicList.
Definition: DynamicListI.H:447
OBJstream os(runTime.globalPath()/outputName)
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats...
Definition: MeshedSurface.H:75
Input from file stream as an ISstream, normally using std::ifstream for the actual input...
Definition: IFstream.H:51
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:405
labelList f(nPoints)
virtual bool read(const fileName &filename) override
Read from file.
void push_back(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:555
label lineNumber() const noexcept
Const access to the current stream line number.
Definition: IOstream.H:390
vector point
Point is a vector.
Definition: point.H:37
const labelUList & faceIds() const noexcept
Const access to the faceIds, zero-sized when unused.
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:281
surface1 clear()
const dimensionedScalar c
Speed of light in a vacuum.
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:412
messageStream Info
Information stream (stdout output on master, null elsewhere)
label n
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
const UList< Face > & surfFaces() const noexcept
Return const access to the faces.
Foam::argList args(argc, argv)
Map< label > invertToMap(const labelUList &values)
Create inverse mapping, which is a lookup table into the given list.
Definition: ListOps.C:107
bool found
streamFormat format() const noexcept
Get the current stream format.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28