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  is.getLine(line);
187 
188  if (NASCore::debug > 1) Info<< "Process: " << line << nl;
189 
190  // ANSA extension(s)
191  if (line.starts_with("$ANSA_NAME"))
192  {
193  // Keep empty elements when splitting
194  const auto args =
195  stringOps::split<std::string>(line, ';', 0, true);
196 
197  if (args.size() > 4 && line.starts_with("$ANSA_NAME_COMMENT"))
198  {
199  // This type of content
200  // $ANSA_NAME_COMMENT;93000;PSHELL;SLIP;;NO;NO;NO;NO;
201 
202  label groupId = 0;
203 
204  if (readLabel(args[1], groupId) && (args[2] == "PSHELL"))
205  {
206  word groupName = word::validate(args[3]);
207 
208  if (!groupName.empty())
209  {
210  DebugInfo
211  << "PSHELL:" << groupId
212  << " = " << groupName << nl;
213 
214  nameLookup.emplace(groupId, std::move(groupName));
215  }
216  }
217 
218  // Handled (or ignored)
219  continue;
220  }
221  else if (args.size() >= 3 && (args[0] == "$ANSA_NAME"))
222  {
223  // This type of content
224 
225  // line 1: $ANSA_NAME;<int>;PSHELL;~
226  // line 2: $some-part-name
227 
228  label groupId = 0;
229 
230  if (readLabel(args[1], groupId) && (args[2] == "PSHELL"))
231  {
232  // Fetch the next line
233  is.getLine(line);
234  line.removeEnd('\r'); // Possible CR-NL
235 
236  word groupName;
237  if (line.starts_with('$'))
238  {
239  groupName = word::validate(line.substr(1));
240  }
241 
242  if (!groupName.empty())
243  {
244  DebugInfo
245  << "PSHELL:" << groupId
246  << " = " << groupName << nl;
247 
248  nameLookup.emplace(groupId, std::move(groupName));
249  }
250  }
251  }
252 
253  // Drop through in case the second line read was not a comment !
254  }
255  else if (line.starts_with("$HMNAME COMP"))
256  {
257  // HYPERMESH extension
258  // This type of content
259  // $HMNAME COMP 1"partName"
260  // [NB: first entry is fixed record length of 32]
261 
262  auto dquote = line.find('"', 12); // Beyond '$HMNAME COMP'
263 
264  label groupId = 0;
265 
266  if
267  (
268  dquote != std::string::npos
269  && readLabel(line.substr(12, (dquote - 12)), groupId)
270  )
271  {
272  // word::validate automatically removes quotes too
273  word groupName = word::validate(line.substr(dquote));
274 
275  if (!groupName.empty())
276  {
277  DebugInfo
278  << "HMNAME group " << groupId
279  << " => " << groupName << nl;
280 
281  nameLookup.emplace(groupId, std::move(groupName));
282  }
283  }
284 
285  continue; // Handled
286  }
287 
288  if (line.empty())
289  {
290  continue; // Ignore empty
291  }
292  else if (line[0] == '$')
293  {
294  // Retain comment (see notes above about weird formats...)
295  lastComment = line;
296  continue;
297  }
298 
299  // Check if character 72 is continuation
300  if (line.size() > 72 && line[72] == '+')
301  {
302  line.resize(72);
303 
304  while (true)
305  {
306  string buf;
307  is.getLine(buf);
308 
309  if (buf.size() > 72 && buf[72] == '+')
310  {
311  line += buf.substr(8, 64);
312  }
313  else
314  {
315  line += buf.substr(8);
316  break;
317  }
318  }
319  }
320 
321 
322  // Parsing position within current line
323  std::string::size_type linei = 0;
324 
325  // Is free format if line contains a comma
326  const bool freeFormat = line.contains(',');
327 
328  // First word (column 0-8)
329  const word cmd(word::validate(nextNasField(line, linei, 8)));
330 
331  if (cmd == "CTRIA3")
332  {
333  // Fixed format:
334  // 8-16 : element id
335  // 16-24 : group id
336  // 24-32 : vertex
337  // 32-40 : vertex
338  // 40-48 : vertex
339 
340  label elemId = readLabel(nextNasField(line, linei, 8, freeFormat));
341  label groupId = readLabel(nextNasField(line, linei, 8, freeFormat));
342  const auto a = readLabel(nextNasField(line, linei, 8, freeFormat));
343  const auto b = readLabel(nextNasField(line, linei, 8, freeFormat));
344  const auto c = readLabel(nextNasField(line, linei, 8, freeFormat));
345 
346  // Convert groupId into zoneId
347  const auto iterZone = zoneLookup.cfind(groupId);
348  if (iterZone.good())
349  {
350  if (zoneId != iterZone.val())
351  {
352  // PSHELL types are intermixed
353  sorted = false;
354  }
355  zoneId = iterZone.val();
356  }
357  else
358  {
359  zoneId = dynSizes.size();
360  zoneLookup.insert(groupId, zoneId);
361  dynSizes.push_back(0);
362  // Info<< "zone" << zoneId << " => group " << groupId <<nl;
363  }
364 
365  --elemId; // Convert 1-based -> 0-based
366  dynElemId.push_back(elemId);
367  dynFaces.push_back(Face{a, b, c});
368  dynZones.push_back(zoneId);
369  dynSizes[zoneId]++;
370  }
371  else if (cmd == "CQUAD4")
372  {
373  // Fixed format:
374  // 8-16 : element id
375  // 16-24 : group id
376  // 24-32 : vertex
377  // 32-40 : vertex
378  // 40-48 : vertex
379  // 48-56 : vertex
380 
381  label elemId = readLabel(nextNasField(line, linei, 8, freeFormat));
382  label groupId = readLabel(nextNasField(line, linei, 8, freeFormat));
383  const auto a = readLabel(nextNasField(line, linei, 8, freeFormat));
384  const auto b = readLabel(nextNasField(line, linei, 8, freeFormat));
385  const auto c = readLabel(nextNasField(line, linei, 8, freeFormat));
386  const auto d = readLabel(nextNasField(line, linei, 8, freeFormat));
387 
388  // Convert groupId into zoneId
389  const auto iterZone = zoneLookup.cfind(groupId);
390  if (iterZone.good())
391  {
392  if (zoneId != iterZone.val())
393  {
394  // PSHELL types are intermixed
395  sorted = false;
396  }
397  zoneId = iterZone.val();
398  }
399  else
400  {
401  zoneId = dynSizes.size();
402  zoneLookup.insert(groupId, zoneId);
403  dynSizes.push_back(0);
404  // Info<< "zone" << zoneId << " => group " << groupId <<nl;
405  }
406 
407  if (faceTraits<Face>::isTri())
408  {
409  ignoreElemId = true;
410  dynElemId.clear();
411 
412  dynFaces.push_back(Face{a, b, c});
413  dynFaces.push_back(Face{c, d, a});
414  dynZones.push_back(zoneId);
415  dynZones.push_back(zoneId);
416  dynSizes[zoneId] += 2;
417  }
418  else
419  {
420  --elemId; // Convert 1-based -> 0-based
421 
422  dynElemId.push_back(elemId);
423  dynFaces.push_back(Face{a,b,c,d});
424  dynZones.push_back(zoneId);
425  dynSizes[zoneId]++;
426  }
427  }
428  else if (cmd == "GRID")
429  {
430  // Fixed (short) format:
431  // 8-16 : point id
432  // 16-24 : coordinate system (not supported)
433  // 24-32 : point x coordinate
434  // 32-40 : point y coordinate
435  // 40-48 : point z coordinate
436  // 48-56 : displacement coordinate system (optional, unsupported)
437  // 56-64 : single point constraints (optional, unsupported)
438  // 64-70 : super-element id (optional, unsupported)
439 
440  label index = readLabel(nextNasField(line, linei, 8, freeFormat));
441  (void) nextNasField(line, linei, 8, freeFormat);
442  scalar x = readNasScalar(nextNasField(line, linei, 8, freeFormat));
443  scalar y = readNasScalar(nextNasField(line, linei, 8, freeFormat));
444  scalar z = readNasScalar(nextNasField(line, linei, 8, freeFormat));
445 
446  pointId.push_back(index);
447  dynPoints.emplace_back(x, y, z);
448  }
449  else if (cmd == "GRID*")
450  {
451  // Long format is on two lines with '*' continuation symbol
452  // on start of second line.
453  // Typical line (spaces compacted)
454  // GRID* 126 0 -5.55999875E+02 -5.68730474E+02
455  // * 2.14897901E+02
456 
457  // Cannot be long format and free format at the same time!
458 
459  label index = readLabel(nextNasField(line, linei, 16)); // 8-24
460  (void) nextNasField(line, linei, 16); // 24-40
461  scalar x = readNasScalar(nextNasField(line, linei, 16)); // 40-56
462  scalar y = readNasScalar(nextNasField(line, linei, 16)); // 56-72
463 
464  linei = 0; // restart at index 0
465  is.getLine(line);
466  if (line[0] != '*')
467  {
469  << "Expected continuation symbol '*' when reading GRID*"
470  << " (double precision coordinate) format" << nl
471  << "Read:" << line << nl
472  << "File:" << is.name() << " line:" << is.lineNumber()
473  << exit(FatalError);
474  }
475  (void) nextNasField(line, linei, 8); // 0-8
476  scalar z = readNasScalar(nextNasField(line, linei, 16)); // 8-16
477 
478  pointId.push_back(index);
479  dynPoints.emplace_back(x, y, z);
480  }
481  else if (cmd == "PSHELL")
482  {
483  // The last ditch effort to map PSHELL id to a group name.
484  // If ANSA or HMNAME didn't work, it is still possible to
485  // have the 'weird' format where the immediately preceeding
486  // comment contains the information.
487 
488  // Fixed format:
489  // 8-16 : pshell id
490 
491  label groupId = readLabel(nextNasField(line, linei, 8, freeFormat));
492 
493  if (lastComment.size() > 1 && !nameLookup.contains(groupId))
494  {
495  word groupName = word::validate(lastComment.substr(1));
496 
497  if (!groupName.empty())
498  {
499  DebugInfo
500  << "PSHELL:" << groupId
501  << " = " << groupName << nl;
502 
503  nameLookup.emplace(groupId, std::move(groupName));
504  }
505  }
506  }
507  else if (unhandledCmd.insert(cmd))
508  {
509  InfoErr
510  << "Unhandled Nastran command " << line << nl
511  << "File:" << is.name() << " line:" << is.lineNumber()
512  << nl;
513  }
514 
515  // Discard buffered comment (from weird format...)
516  lastComment.clear();
517  }
518 
519 
520  // Info<< "Read faces:" << dynFaces.size()
521  // << " points:" << dynPoints.size()
522  // << endl;
523 
524  if (ignoreElemId)
525  {
526  dynElemId.clear();
527  }
528 
529  // Transfer to normal lists
530  this->storedPoints().transfer(dynPoints);
531 
532  dynFaces.shrink();
533 
534  // Build inverse mapping (NASTRAN pointId -> index)
535  Map<label> mapPointId(invertToMap(pointId));
536  pointId.clearStorage();
537 
538  // Relabel faces
539  // ~~~~~~~~~~~~~
540  for (Face& f : dynFaces)
541  {
542  for (label& vert : f)
543  {
544  vert = mapPointId[vert];
545  }
546  }
547  mapPointId.clear();
548 
549  DebugInfo
550  << "PSHELL names:" << nameLookup << nl;
551 
552  // Create default zone names, or from ANSA/Hypermesh information
553  List<word> names(dynSizes.size());
554  forAllConstIters(zoneLookup, iter)
555  {
556  const label groupId = iter.key();
557  const label zoneId = iter.val();
558 
559  const auto iterName = nameLookup.cfind(groupId);
560  if (iterName.good())
561  {
562  names[zoneId] = iterName.val();
563  }
564  else
565  {
566  names[zoneId] = surfZone::defaultName(zoneId);
567  }
568  }
569 
570  this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
571 
572  // Add zones (retaining empty ones)
573  this->addZones(dynSizes, names);
574  this->addZonesToFaces(); // for labelledTri
576  return true;
577 }
578 
579 
580 template<class Face>
582 (
583  const fileName& filename,
584  const MeshedSurfaceProxy<Face>& surf,
585  IOstreamOption streamOpt,
586  const dictionary&
587 )
588 {
589  // ASCII only, allow output compression
590  streamOpt.format(IOstreamOption::ASCII);
591 
592  const UList<point>& pointLst = surf.points();
593  const UList<Face>& faceLst = surf.surfFaces();
594  const UList<label>& faceMap = surf.faceMap();
595  const UList<label>& elemIds = surf.faceIds();
596 
597  // for no zones, suppress the group name
598  const surfZoneList zones =
599  (
600  surf.surfZones().empty()
601  ? surfaceFormatsCore::oneZone(faceLst, "")
602  : surf.surfZones()
603  );
604 
605  const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
606 
607  // Possible to use faceIds?
608  // - cannot if there are negative ids (eg, encoded solid/side)
609  bool useOrigFaceIds =
610  (
611  !useFaceMap
612  && elemIds.size() == faceLst.size()
613  && !ListOps::found(elemIds, lessOp1<label>(0))
614  );
615 
616  // Not possible with on-the-fly face decomposition
617  if (useOrigFaceIds)
618  {
619  for (const auto& f : faceLst)
620  {
621  if (f.size() > 4)
622  {
623  useOrigFaceIds = false;
624  break;
625  }
626  }
627  }
628 
629 
630  OFstream os(filename, streamOpt);
631  if (!os.good())
632  {
634  << "Cannot write file " << filename << nl
635  << exit(FatalError);
636  }
637 
638  // For simplicity, use fieldFormat::FREE throughout
639  fileFormats::NASCore::setPrecision(os, fieldFormat::FREE);
640 
641  os << "CEND" << nl
642  << "TITLE = " << os.name().stem() << nl;
643 
644  // Print zone names as comment
645  forAll(zones, zonei)
646  {
647  // HYPERMESH extension
648  os << "$HMNAME COMP" << setw(20) << (zonei+1)
649  << '"' << zones[zonei].name() << '"' << nl;
650  }
651 
652  // Write vertex coords with 1-based point Id
653  os << "$ GRID POINTS" << nl
654  << "BEGIN BULK" << nl;
655 
656  label pointId = 0;
657  for (const point& pt : pointLst)
658  {
659  os << "GRID" << ','
660  << ++pointId << ','
661  << 0 << ',' // global coordinate system
662  << pt.x() << ',' << pt.y() << ',' << pt.z() << nl;
663  }
664 
665  os << "$ ELEMENTS" << nl;
666 
667  label faceIndex = 0;
668  label zoneIndex = 0;
669  label elemId = 0;
670 
671  for (const surfZone& zone : zones)
672  {
673  for (label nLocal = zone.size(); nLocal--; ++faceIndex)
674  {
675  const label facei =
676  (useFaceMap ? faceMap[faceIndex] : faceIndex);
677 
678  const Face& f = faceLst[facei];
679 
680  if (useOrigFaceIds)
681  {
682  elemId = elemIds[facei];
683  }
684 
685  elemId = writeShell(os, f, elemId, zoneIndex);
686  }
687 
688  ++zoneIndex;
689  }
690 
691  os << "ENDDATA" << nl;
692 }
693 
694 
695 // ************************************************************************* //
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