ABAQUSCore.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) 2020 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 "ABAQUSCore.H"
29 #include "IFstream.H"
30 #include "ListOps.H"
31 #include "stringOps.H"
32 #include "UIListStream.H"
33 
34 #undef Foam_readAbaqusSurface
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
39 
40 
41 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 
46 // Use peek(), get(), unget() to detect and skip lines that appear to be
47 // "** comment" lines.
48 //
49 // Uses a mix of std::istream and ISstream methods
50 // since we need the low-level get()/unget()
51 
52 static void skipComments(ISstream& iss)
53 {
54  #if OPENFOAM < 2002
55  string line;
56  #endif
57 
58  auto& is = iss.stdStream();
59 
60  bool isComment = true;
61  while (isComment)
62  {
63  isComment = ('*' == is.peek());
64 
65  if (isComment)
66  {
67  // Get and check the next one
68  (void) is.get();
69 
70  isComment = ('*' == is.peek());
71  if (isComment)
72  {
73  // Found "** ..." (a comment) - read/discard
74  // ISstream::getLine to keep track of the line numbers
75 
76  #if OPENFOAM >= 2002
77  iss.getLine(nullptr);
78  #else
79  iss.getLine(line);
80  #endif
81  }
82  else
83  {
84  // Not a comment
85  // - unget the '*', implicitly break out of loop
86  is.unget();
87  }
88  }
89  }
90 }
91 
92 
93 // Get an identifier of the form "NSET=..." (case-insensitive)
94 // Return the string on success, an empty string on failure
95 
96 static string getIdentifier(const word& keyword, string& inputLine)
97 {
98  // Strip out whitespace (not a valid Abaqus identifier anyhow)
99  // - makes parsing easier, avoids tab/carriage-returns etc.
100 
102 
103  // Do string comparisons in upper-case
104 
105  const auto key(stringOps::upper(keyword));
106  const auto line(stringOps::upper(inputLine));
107 
108  // Extract "..,key=value,key2=value,"
109 
110  // Not sure if we need the additional ',' prefix
111  // in search to avoid similar keys.
112 
113  auto beg = line.find("," + key + "=");
114 
115  if (beg != std::string::npos)
116  {
117  // Skip past the '='
118  beg += key.size() + 2;
119 
120  // The closing comma
121  auto len = line.find(',', beg);
122  if (len != std::string::npos)
123  {
124  len -= beg;
125  }
126 
127  // Substring from inputLine (not uppercase!)
128  return inputLine.substr(beg, len);
129  }
130 
131  // Not found
132  return string();
133 }
134 
135 
136 // Walk the string content (CSV format) to append integer labels
137 // until the line is exhausted or the list is full.
138 //
139 // Return false on read error or if the line exhausted while getting
140 // element.
141 
142 static bool appendCsvLabels
143 (
144  const std::string& line,
145  labelUList& elemNodes,
146  label& nodei
147 )
148 {
149  const label nNodes = elemNodes.size();
150 
151  std::size_t pos = 0;
152 
153  while (nodei < nNodes && pos != std::string::npos)
154  {
155  auto beg = pos;
156  auto len = line.find(',', pos);
157 
158  if (len == std::string::npos)
159  {
160  pos = len;
161  }
162  else
163  {
164  pos = len + 1;
165  len -= beg;
166  }
167 
168  if (readLabel(line.substr(beg, len), elemNodes[nodei]))
169  {
170  ++nodei;
171  }
172  else
173  {
174  // Read error, or need another line
175  return false;
176  }
177  }
178 
179  return (nodei >= nNodes);
180 }
181 
182 
183 } // End namespace Foam
184 
185 
186 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
187 
190 {
191  if (abaqusToFoamFaceAddr_.empty())
192  {
193  abaqusToFoamFaceAddr_.emplace(abaqusTet, labelList({3, 2, 0, 1}));
194  abaqusToFoamFaceAddr_.emplace(abaqusPrism, labelList({0, 1, 4, 3, 2}));
195  abaqusToFoamFaceAddr_.emplace(abaqusHex, labelList({4, 5, 2, 1, 3, 0}));
196  }
197 
198  return abaqusToFoamFaceAddr_;
199 }
200 
201 
203 Foam::fileFormats::ABAQUSCore::getElementType(const std::string& elemTypeName)
204 {
205  // Check for element-type
206  #undef checkElemType
207  #define checkElemType(test) (elemTypeName.find(test) != std::string::npos)
208 
209  if
210  (
211  checkElemType("S3")
212  || checkElemType("CPE3")
213  || checkElemType("2D3")
214  )
215  {
216  return shapeType::abaqusTria;
217  }
218  else if
219  (
220  checkElemType("S4")
221  || checkElemType("CPE4")
222  || checkElemType("2D4")
223  || checkElemType("CPEG4")
224  )
225  {
226  return shapeType::abaqusQuad;
227  }
228  else if
229  (
230  checkElemType("3D4") // C3D4*, Q3D4, ...
231  )
232  {
233  return shapeType::abaqusTet;
234  }
235  else if
236  (
237  checkElemType("3D5") // C3D5*
238  )
239  {
240  return shapeType::abaqusPyr;
241  }
242  else if
243  (
244  checkElemType("3D6") // C3D6*
245  )
246  {
247  return shapeType::abaqusPrism;
248  }
249  else if
250  (
251  checkElemType("3D8") // C3D8*
252  )
253  {
254  return shapeType::abaqusHex;
255  }
256 
257  #undef checkElemType
258 
259  return shapeType::abaqusUnknownShape;
260 }
261 
262 
263 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
264 
265 Foam::label
267 (
268  const std::string& setName
269 )
270 {
271  if (elsetMap_.empty())
272  {
273  // Always have a lookup for empty string
274  elsetMap_.set(string::null, 0);
275  }
276 
277  if (setName.empty())
278  {
279  return 0;
280  }
281 
282  // Direct case-sensitive lookup - it might be there
283 
284  label setId = elsetMap_.lookup(setName, -1);
285  if (setId >= 0)
286  {
287  return setId;
288  }
289 
290 
291  // Case-insensitive search, use upper-case
292 
293  const auto needle(stringOps::upper(setName));
294 
295  forAllConstIters(elsetMap_, iter)
296  {
297  const auto haystack(stringOps::upper(iter.key()));
298 
299  if (needle == haystack)
300  {
301  return iter.val();
302  }
303  }
304 
305  // Not there. Save at the next location
306  setId = elsetMap_.size();
307  elsetMap_.set(setName, setId);
308 
309  return setId;
310 }
311 
312 
313 Foam::label
315 (
316  ISstream& is
317 )
318 {
319  const label initialCount = points_.size();
320 
321  char sep; // Comma separator (dummy)
322  label id;
323  point p;
324 
325  string line;
326 
327  // Read nodes (points) until next "*Section"
328  while (is.peek() != '*' && is.peek() != EOF)
329  {
330  // Grab the line and wrap as string-stream
331  is.getLine(line);
332  UIListStream ss(line.data(), line.length());
333 
334  if (line.empty())
335  {
336  // Not sure if we should terminate on blank lines?
337  continue;
338  }
339 
340  // Parse line for ID, X, Y, Z
341  ss >> id >> sep >> p.x() >> sep >> p.y() >> sep >> p.z();
342 
343  nodeIds_.append(id);
344  points_.append(p);
345  }
346 
347  return (points_.size() - initialCount);
348 }
349 
350 
351 Foam::label
353 (
354  ISstream& is,
355  const ABAQUSCore::shapeType shape,
356  const label setId
357 )
358 {
359  // Info<< "*Element" << nl;
360 
361  const label nNodes = ABAQUSCore::nPoints(shape);
362 
363  if (!nNodes)
364  {
365  return 0;
366  }
367 
368  const label initialCount = elemTypes_.size();
369 
370  char sep; // Comma separator (dummy)
371  label id;
372  labelList elemNodes(nNodes, Zero);
373 
374  string line;
375 
376  // Read element connectivity until next "*Section"
377 
378  // Parse for ID, node1, node2, ...
379  while (is.peek() != '*' && is.peek() != EOF)
380  {
381  // elemNodes = Zero; for sanity checks?
382 
383  is >> id >> sep;
384 
385  label nodei = 0;
386  while (nodei < nNodes)
387  {
388  // Grab the rest of the line, walk through CSV fields
389  is.getLine(line);
390 
391  appendCsvLabels(line, elemNodes, nodei);
392  }
393 
394  // Checks?
395 
396  connectivity_.append(elemNodes);
397  elemTypes_.append(shape);
398  elemIds_.append(id);
399  elsetIds_.append(setId);
400  }
401 
402  return (elemTypes_.size() - initialCount);
403 }
404 
405 
407 (
408  ISstream& is
409 )
410 {
411  clear();
412 
413  label nread;
414  string line;
415 
416  while (is.good())
417  {
418  is.getLine(line);
419 
420  // Start processing on "*Section-Name",
421  // but skip "** comments" etc
422  if (line[0] != '*' || !std::isalpha(line[1]))
423  {
424  continue;
425  }
426 
427  // Some abaqus files use upper-case or mixed-case for section names,
428  // convert all to upper-case for ease.
429 
430  string upperLine(stringOps::upper(line));
431 
432  // "*Nodes" section
433  if (upperLine.starts_with("*NODE"))
434  {
435  // Ignore "NSET=...", we cannot do anything useful with it
436 
437  skipComments(is);
438 
439  nread = readPoints(is);
440 
441  if (verbose_)
442  {
443  InfoErr
444  << "Read " << nread << " *NODE entries" << nl;
445  }
446  continue;
447  }
448 
449  // "*Element" section
450  if (upperLine.starts_with("*ELEMENT,"))
451  {
452  // Must have "TYPE=..."
453  auto elemTypeName = getIdentifier("TYPE", line);
454 
455  // May have "ELSET=..." on the same line
456  string elsetName(getIdentifier("ELSET", line));
457 
458  const shapeType shape(getElementType(elemTypeName));
459 
460  if (!ABAQUSCore::nPoints(shape))
461  {
462  // Unknown/unsupported
463  if (verbose_)
464  {
465  InfoErr
466  << "Ignore abaqus element type: "
467  << elemTypeName << nl;
468  }
469  continue;
470  }
471 
472  const label elsetId = addNewElset(elsetName);
473 
474  skipComments(is);
475 
476  nread = readElements(is, shape, elsetId);
477 
478  if (verbose_)
479  {
480  InfoErr
481  << "Read " << nread << " *ELEMENT entries ("
482  << elemTypeName << ") elset="
483  << elsetName << nl;
484  }
485  continue;
486  }
487 
488 
489  // "*Surface" section
490  if (upperLine.starts_with("*SURFACE,"))
491  {
492  #ifdef Foam_readAbaqusSurface
493 
494  skipComments(is);
495 
496  #else
497  Info<< "Reading of abaqus surfaces not implemented" << nl;
498  #endif
499 
500  continue;
501  }
502  }
503 }
504 
505 
507 {
508  // Negative set
509  bitSet select(elemTypes_.size(), false);
510 
511  forAll(elemTypes_, i)
512  {
513  if (!isValidType(elemTypes_[i]) || isSolidType(elemTypes_[i]))
514  {
515  select.set(i);
516  }
517  }
518 
519  if (select.any())
520  {
521  select.flip();
522 
523  inplaceSubset(select, connectivity_);
524  inplaceSubset(select, elemTypes_);
525 
526  inplaceSubset(select, elemIds_);
527  inplaceSubset(select, elsetIds_);
528  }
529 }
530 
531 
533 {
534  if (!nodeIds_.empty())
535  {
536  // Has original 1-based ids
537  //
538  // Need to convert to local (0-based) points
539  // in the order in which we read them
540  // and compact unused values
541 
542  // Could construct a sort order to preserve the original
543  // point order, but that is not likely relevant for anyone.
544 
545 
546  // Which original node ids actually being used by elements?
547 
548  // We may have many ids, but speculate that they are sparse
549  // and have high element numbers.
550 
551  // Use a Map instead of labelList.
552 
553  Map<label> nodeIdRemapping(2*points_.size());
554 
555  // Pass 1: which nodes are being used?
556 
557  for (const labelList& elem : connectivity_)
558  {
559  for (const label origId : elem)
560  {
561  nodeIdRemapping(origId) = 0; // any value
562  }
563  }
564 
565  // Define compact local points, finalize the node id remapping
566 
567  label nPoints = 0;
568  labelList oldToNewLocal(nodeIds_.size(), -1);
569 
570  forAll(nodeIds_, i)
571  {
572  const label origId = nodeIds_[i];
573 
574  if (nodeIdRemapping.found(origId))
575  {
576  oldToNewLocal[i] = nPoints;
577  nodeIdRemapping(origId) = nPoints;
578  ++nPoints;
579  }
580  }
581 
582  // Prune out -1 values (shrinks list)
583  inplaceReorder(oldToNewLocal, points_, true);
584 
585  // Relabel the elements
586 
587  for (labelList& elem : connectivity_)
588  {
589  for (label& id : elem)
590  {
591  id = nodeIdRemapping[id];
592  }
593  }
594 
595  // Done!
596  nodeIds_.clear();
597  }
598  else
599  {
600  // Already numbered (0-based), but perhaps not compacted
601 
602  // Which node ids actually being used by elements?
603  bitSet usedNodeIds(points_.size());
604 
605  for (const labelList& elem : connectivity_)
606  {
607  usedNodeIds.set(elem);
608  }
609 
610  // Compact the numbers
611  labelList oldToNewLocal = invert(points_.size(), usedNodeIds);
612 
613  // Prune out -1 values (shrinks list)
614  inplaceReorder(oldToNewLocal, points_, true);
615 
616 
617  // Renumber non-compact to compact
618  for (labelList& elem : connectivity_)
619  {
620  inplaceRenumber(oldToNewLocal, elem);
621  }
622  }
623 }
624 
625 
627 (
628  Ostream& os,
629  const UList<point>& points,
630  const scalar scaleFactor
631 )
632 {
633  if (points.empty())
634  {
635  return;
636  }
637 
638  // Set the precision of the points data to 10
639  os.precision(10);
640 
641  // Force decimal point for Fortran input
642  os.setf(std::ios::showpoint);
643 
644  label vertId = 1; // 1-based vertex labels
645 
646  os << "*NODE" << nl;
647  for (const point& p : points)
648  {
649  // Convert [m] -> [mm] etc
650  os << " "
651  << vertId << ", "
652  << (scaleFactor * p.x()) << ','
653  << (scaleFactor * p.y()) << ','
654  << (scaleFactor * p.z()) << nl;
655 
656  ++vertId;
657  }
658 }
659 
660 
662 (
663  const UList<point>& points,
664  const UList<face>& faces,
665  labelList& decompOffsets,
666  DynamicList<face>& decompFaces
667 )
668 {
669  // On-demand face decomposition (triangulation)
670 
671  decompOffsets.resize(faces.size()+1);
672  decompFaces.clear();
673 
674  auto offsetIter = decompOffsets.begin();
675  *offsetIter = 0; // The first offset is always zero
676 
677  for (const face& f : faces)
678  {
679  const label n = f.size();
680 
681  if (n != 3 && n != 4)
682  {
683  // Decompose non-tri/quad into tris
684  f.triangles(points, decompFaces);
685  }
686 
687  // The end offset, which is the next begin offset
688  *(++offsetIter) = decompFaces.size();
689  }
690 
691  return decompFaces.size();
692 }
693 
694 
695 // ************************************************************************* //
Foam::fileFormats::ABAQUSCore::readHelper::readElements
label readElements(ISstream &is, const ABAQUSCore::shapeType shape, const label setId=0)
Read entries within an "*Element" section.
Definition: ABAQUSCore.C:353
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::ISstream::peek
int peek()
Raw, low-level peek function.
Definition: ISstreamI.H:70
Foam::fileFormats::ABAQUSCore::readHelper::addNewElset
label addNewElset(const std::string &setName)
Add a new element set name or return an existing one.
Definition: ABAQUSCore.C:267
Foam::UIListStream
Similar to IStringStream but using an externally managed buffer for its input. This allows the input ...
Definition: UIListStream.H:202
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::ISstream::getLine
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:76
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:64
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::string::starts_with
bool starts_with(const std::string &s) const
True if string starts with the given prefix (cf. C++20)
Definition: string.H:299
Foam::ISstream
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:55
Foam::fileFormats::ABAQUSCore::readHelper::read
void read(ISstream &is)
Read an abaqus input file.
Definition: ABAQUSCore.C:407
Foam::bitSet::set
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:563
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: lumpedPointController.H:69
Foam::string
A class for handling character strings derived from std::string.
Definition: string.H:73
Foam::InfoErr
messageStream InfoErr
Information stream (uses stderr - output is on the master only)
Foam::invert
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:36
Foam::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:61
Foam::Ostream::precision
virtual int precision() const =0
Get precision of output field.
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::ISstream::get
ISstream & get(char &c)
Raw, low-level get character function.
Definition: ISstreamI.H:56
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::fileFormats::ABAQUSCore::readHelper::compact_nodes
void compact_nodes()
Compact unused points and relabel connectivity.
Definition: ABAQUSCore.C:532
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::fileFormats::ABAQUSCore::getElementType
static shapeType getElementType(const std::string &elemTypeName)
Definition: ABAQUSCore.C:203
Foam::fileFormats::ABAQUSCore::readHelper::readPoints
label readPoints(ISstream &is)
Read entries within a "*Nodes" section.
Definition: ABAQUSCore.C:315
Foam::getIdentifier
static string getIdentifier(const word &keyword, string &inputLine)
Definition: ABAQUSCore.C:96
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::fileFormats::ABAQUSCore::abaqusPrism
Definition: ABAQUSCore.H:258
abaqusToFoamFaceAddr_
static Foam::Map< Foam::labelList > abaqusToFoamFaceAddr_
Definition: ABAQUSCore.C:38
UIListStream.H
Foam::fileFormats::ABAQUSCore::nPoints
static int nPoints(shapeType tag)
The number of points associated with the element type.
Definition: ABAQUSCore.H:271
Foam::DynamicList::clear
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:348
Foam::fileFormats::ABAQUSCore::faceDecomposition
static label faceDecomposition(const UList< point > &points, const UList< face > &faces, labelList &decompOffsets, DynamicList< face > &decompFaces)
Calculate face decomposition for non tri/quad faces.
Definition: ABAQUSCore.C:662
Foam::fileFormats::ABAQUSCore::abaqusToFoamFaceAddr
static const Map< labelList > & abaqusToFoamFaceAddr()
Face addressing from ABAQUS faces to OpenFOAM faces.
Definition: ABAQUSCore.C:189
checkElemType
#define checkElemType(test)
IFstream.H
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::string::null
static const string null
An empty string.
Definition: string.H:147
Foam::fileFormats::ABAQUSCore::abaqusHex
Definition: ABAQUSCore.H:259
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::inplaceSubset
void inplaceSubset(const BoolListType &select, ListType &input, const bool invert=false)
Inplace extract elements of the input list when select is true.
Definition: ListOpsTemplates.C:590
Foam::IOstream::setf
ios_base::fmtflags setf(const ios_base::fmtflags f)
Set flags of stream.
Definition: IOstream.H:369
Foam::fileFormats::ABAQUSCore::readHelper::purge_solids
void purge_solids()
Remove non-shell elements and compact the points.
Definition: ABAQUSCore.C:506
Foam::fileFormats::ABAQUSCore::abaqusTet
Definition: ABAQUSCore.H:256
Foam::ISstream::stdStream
virtual std::istream & stdStream()
Access to underlying std::istream.
Definition: ISstream.H:209
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:385
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::stringOps::inplaceRemoveSpace
void inplaceRemoveSpace(std::string &s)
Eliminate whitespace inplace.
Definition: stringOps.C:1076
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::readLabel
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
Foam::appendCsvLabels
static bool appendCsvLabels(const std::string &line, labelUList &elemNodes, label &nodei)
Definition: ABAQUSCore.C:143
Foam::List< label >
Foam::fileFormats::ABAQUSCore::shapeType
shapeType
Shape-Type - the values are for internal use only!
Definition: ABAQUSCore.H:251
Foam::UList< label >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::line
A line primitive.
Definition: line.H:59
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
ABAQUSCore.H
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:124
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
ListOps.H
Various functions to operate on Lists.
Foam::fileFormats::ABAQUSCore::writePoints
static void writePoints(Ostream &os, const UList< point > &points, const scalar scaleFactor=1.0)
Write '*NODE' header and entries to file, optionally with scaling.
Definition: ABAQUSCore.C:627
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::stringOps::upper
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1202
Foam::IOstream::good
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:224
stringOps.H
Foam::skipComments
static void skipComments(ISstream &iss)
Definition: ABAQUSCore.C:52
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177