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-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 "ABAQUSCore.H"
29 #include "IFstream.H"
30 #include "ListOps.H"
31 #include "stringOps.H"
32 #include "SpanStream.H"
33 #include "cellModel.H"
34 #include <cctype>
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  iss.syncState();
92 }
93 
94 
95 // Get an identifier of the form "NSET=..." (case-insensitive)
96 // Return the string on success, an empty string on failure
97 
98 static string getIdentifier(const word& keyword, string& inputLine)
99 {
100  // Strip out whitespace (not a valid Abaqus identifier anyhow)
101  // - makes parsing easier, avoids tab/carriage-returns etc.
102 
104 
105  // Do string comparisons in upper-case
106 
107  const auto key(stringOps::upper(keyword));
108  const auto line(stringOps::upper(inputLine));
109 
110  // Extract "..,key=value,key2=value,"
111 
112  // Not sure if we need the additional ',' prefix
113  // in search to avoid similar keys.
114 
115  auto beg = line.find("," + key + "=");
116 
117  if (beg != std::string::npos)
118  {
119  // Skip past the '='
120  beg += key.size() + 2;
121 
122  // The closing comma
123  auto len = line.find(',', beg);
124  if (len != std::string::npos)
125  {
126  len -= beg;
127  }
128 
129  // Substring from inputLine (not uppercase!)
130  return inputLine.substr(beg, len);
131  }
132 
133  // Not found
134  return string();
135 }
136 
137 
138 // Walk the string content (CSV format) to append integer labels
139 // until the line is exhausted or the list is full.
140 //
141 // Return false on read error or if the line exhausted while getting
142 // element.
143 
144 static bool appendCsvLabels
145 (
146  const std::string& line,
147  labelUList& elemNodes,
148  label& nodei
149 )
150 {
151  const label nNodes = elemNodes.size();
152 
153  std::size_t pos = 0;
154 
155  while (nodei < nNodes && pos != std::string::npos)
156  {
157  auto beg = pos;
158  auto len = line.find(',', pos);
159 
160  if (len == std::string::npos)
161  {
162  pos = len;
163  }
164  else
165  {
166  pos = len + 1;
167  len -= beg;
168  }
169 
170  if (readLabel(line.substr(beg, len), elemNodes[nodei]))
171  {
172  ++nodei;
173  }
174  else
175  {
176  // Read error, or need another line
177  return false;
178  }
179  }
180 
181  return (nodei >= nNodes);
182 }
183 
185 } // End namespace Foam
186 
187 
188 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
189 
192 {
193  if (abaqusToFoamFaceAddr_.empty())
194  {
195  abaqusToFoamFaceAddr_.emplace(abaqusTet, labelList({3, 2, 0, 1}));
196  abaqusToFoamFaceAddr_.emplace(abaqusPrism, labelList({0, 1, 4, 3, 2}));
197  abaqusToFoamFaceAddr_.emplace(abaqusHex, labelList({4, 5, 2, 1, 3, 0}));
198  }
199 
200  return abaqusToFoamFaceAddr_;
201 }
202 
203 
205 Foam::fileFormats::ABAQUSCore::getElementType(const string& elemTypeName)
206 {
207  // Check for element-type.
208  #undef checkElemType
209  #define checkElemType(Name) elemTypeName.contains(Name)
210 
211  if
212  (
213  checkElemType("S3")
214  || checkElemType("CPE3")
215  || checkElemType("2D3")
216  )
217  {
218  return shapeType::abaqusTria;
219  }
220  else if
221  (
222  checkElemType("S4")
223  || checkElemType("CPE4")
224  || checkElemType("2D4")
225  || checkElemType("CPEG4")
226  )
227  {
228  return shapeType::abaqusQuad;
229  }
230  else if
231  (
232  checkElemType("3D4") // C3D4*, Q3D4, ...
233  )
234  {
235  return shapeType::abaqusTet;
236  }
237  else if
238  (
239  checkElemType("3D5") // C3D5*
240  )
241  {
242  return shapeType::abaqusPyr;
243  }
244  else if
245  (
246  checkElemType("3D6") // C3D6*
247  )
248  {
249  return shapeType::abaqusPrism;
250  }
251  else if
252  (
253  checkElemType("3D8") // C3D8*
254  )
255  {
256  return shapeType::abaqusHex;
257  }
258 
259  #undef checkElemType
260 
261  return shapeType::abaqusUnknownShape;
262 }
263 
264 
265 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
266 
267 Foam::label
269 (
270  const std::string& setName
271 )
272 {
273  if (elsetMap_.empty())
274  {
275  // Always have a lookup for empty string
276  elsetMap_.set(string::null, 0);
277  }
278 
279  if (setName.empty())
280  {
281  return 0;
282  }
283 
284  // Direct case-sensitive lookup - it might be there
285 
286  label setId = elsetMap_.lookup(setName, -1);
287  if (setId >= 0)
288  {
289  return setId;
290  }
291 
292 
293  // Case-insensitive search, use upper-case
294 
295  const auto needle(stringOps::upper(setName));
296 
297  forAllConstIters(elsetMap_, iter)
298  {
299  const auto haystack(stringOps::upper(iter.key()));
300 
301  if (needle == haystack)
302  {
303  return iter.val();
304  }
305  }
306 
307  // Not there. Save at the next location
308  setId = elsetMap_.size();
309  elsetMap_.set(setName, setId);
311  return setId;
312 }
313 
314 
315 Foam::label
317 (
318  ISstream& is
319 )
320 {
321  const label initialCount = points_.size();
322 
323  char sep; // Comma separator (dummy)
324  string line;
325  label id;
326  point p;
327 
328  // Read nodes (points) until next "*Section"
329  while (is.peek() != '*' && is.peek() != EOF)
330  {
331  // Grab the line and wrap as spanstream
332  is.getLine(line);
333 
334  if (line.empty())
335  {
336  // Not sure if we should terminate on blank lines?
337  continue;
338  }
339  ISpanStream ss(line);
340 
341  // Parse line for ID, X, Y, Z
342  ss >> id >> sep >> p.x() >> sep >> p.y() >> sep >> p.z();
343 
344  nodeIds_.append(id);
345  points_.append(p);
346  }
348  return (points_.size() - initialCount);
349 }
350 
351 
352 Foam::label
354 (
355  ISstream& is,
356  const ABAQUSCore::shapeType shape,
357  const label setId
358 )
359 {
360  // Info<< "*Element" << nl;
361 
362  const label nNodes = ABAQUSCore::nPoints(shape);
363 
364  if (!nNodes)
365  {
366  return 0;
367  }
368 
369  const label initialCount = elemTypes_.size();
370 
371  char sep; // Comma separator (dummy)
372  string line;
373  label id;
374 
375  labelList elemNodes(nNodes, Zero);
376 
377  // Read element connectivity until next "*Section"
378 
379  // Parse for ID, node1, node2, ...
380  while (is.peek() != '*' && is.peek() != EOF)
381  {
382  // elemNodes = Zero; for sanity checks?
383 
384  is >> id >> sep;
385 
386  label nodei = 0;
387  while (nodei < nNodes)
388  {
389  // Grab the rest of the line, walk through CSV fields
390  is.getLine(line);
391 
392  appendCsvLabels(line, elemNodes, nodei);
393  }
394 
395  // Checks?
396 
397  connectivity_.append(elemNodes);
398  elemTypes_.append(shape);
399  elemIds_.append(id);
400  elsetIds_.append(setId);
401  }
403  return (elemTypes_.size() - initialCount);
404 }
405 
406 
407 Foam::label
409 (
410  ISstream& is,
411  const label setId
412 )
413 {
414  // Info<< "*Surface" << nl;
415 
416  // Models for supported solids (need to face mapping)
418  const cellModel& prism = cellModel::ref(cellModel::PRISM);
420 
421  // Face mapping from Abaqus cellModel to OpenFOAM cellModel
422  const auto& abqToFoamFaceMap = abaqusToFoamFaceAddr();
423 
424  const label initialCount = elemTypes_.size();
425 
426  char sep; // Comma separator (dummy)
427  string line;
428  label id;
429 
430  // Read until next "*Section"
431 
432  // Parse for elemId, sideId.
433  // Eg, "1235, S1"
434  while (is.peek() != '*' && is.peek() != EOF)
435  {
436  is >> id >> sep;
437  is.getLine(line);
438 
439  const word sideName(word::validate(stringOps::upper(line)));
440 
441  if
442  (
443  sideName.size() != 2
444  || sideName[0] != 'S'
445  || !std::isdigit(sideName[1])
446  )
447  {
448  Info<< "Abaqus reader: unsupported surface element side "
449  << id << ", " << sideName << nl;
450  continue;
451  }
452 
453  const label index = elemIds_.find(id);
454  if (id <= 0 || index < 0)
455  {
456  Info<< "Abaqus reader: unsupported surface element "
457  << id << nl;
458  continue;
459  }
460 
461  const auto faceIdIter = abqToFoamFaceMap.cfind(elemTypes_[index]);
462  if (!faceIdIter.good())
463  {
464  Info<< "Abaqus reader: reject non-solid shape: " << nl;
465  }
466 
467  // The abaqus element side number (1-based)
468  const label sideNum = (sideName[1] - '0');
469 
470  const label foamFaceNum = (*faceIdIter)[sideNum - 1];
471 
472  const labelList& connect = connectivity_[index];
473 
474  // Nodes for the derived shell element
475  labelList elemNodes;
476 
477  switch (elemTypes_[index])
478  {
479  case shapeType::abaqusTet:
480  {
481  elemNodes = labelList(connect, tet.modelFaces()[foamFaceNum]);
482  break;
483  }
484  case shapeType::abaqusPrism:
485  {
486  elemNodes = labelList(connect, prism.modelFaces()[foamFaceNum]);
487  break;
488  }
489  case shapeType::abaqusHex:
490  {
491  elemNodes = labelList(connect, hex.modelFaces()[foamFaceNum]);
492  break;
493  }
494  default:
495  break;
496  }
497 
498  enum shapeType shape = shapeType::abaqusUnknownShape;
499 
500  if (elemNodes.size() == 3)
501  {
502  shape = shapeType::abaqusTria;
503  }
504  else if (elemNodes.size() == 4)
505  {
506  shape = shapeType::abaqusQuad;
507  }
508  else
509  {
510  // Cannot happen
512  << "Could not map face side for "
513  << id << ", " << sideName << nl
514  << exit(FatalError);
515  }
516 
517  // Synthesize face Id from solid element Id and side Id
518  const label newElemId = ABAQUSCore::encodeSolidId(id, sideNum);
519 
520  // Further checks?
521  connectivity_.append(std::move(elemNodes));
522  elemTypes_.append(shape);
523  elemIds_.append(newElemId);
524  elsetIds_.append(setId);
525  }
526 
527  return (elemTypes_.size() - initialCount);
528 }
529 
530 
532 (
533  ISstream& is
534 )
535 {
536  clear();
537 
538  label nread;
539  string line;
540 
541  while (is.good())
542  {
543  is.getLine(line);
544 
545  // Start processing on "*Section-Name",
546  // but skip "** comments" etc
547  if (line[0] != '*' || !std::isalpha(line[1]))
548  {
549  continue;
550  }
551 
552  // Some abaqus files use upper-case or mixed-case for section names,
553  // convert all to upper-case for ease.
554 
555  const string upperLine(stringOps::upper(line));
556 
557  //
558  // "*Nodes" section
559  //
560  if (upperLine.starts_with("*NODE"))
561  {
562  // Ignore "NSET=...", we cannot do anything useful with it
563 
564  skipComments(is);
565 
566  nread = readPoints(is);
567 
568  if (verbose_)
569  {
570  InfoErr
571  << "Read " << nread << " *NODE entries" << nl;
572  }
573  continue;
574  }
575 
576  //
577  // "*Element" section
578  //
579  if (upperLine.starts_with("*ELEMENT,"))
580  {
581  // Must have "TYPE=..."
582  const string elemTypeName(getIdentifier("TYPE", line));
583 
584  // May have "ELSET=..." on the same line
585  const string elsetName(getIdentifier("ELSET", line));
586 
587  const shapeType shape(getElementType(elemTypeName));
588 
589  if (!ABAQUSCore::nPoints(shape))
590  {
591  // Unknown/unsupported
592  if (verbose_)
593  {
594  InfoErr
595  << "Ignore abaqus element type: "
596  << elemTypeName << nl;
597  }
598  continue;
599  }
600 
601  const label elsetId = addNewElset(elsetName);
602 
603  skipComments(is);
604 
605  nread = readElements(is, shape, elsetId);
606 
607  if (verbose_)
608  {
609  InfoErr
610  << "Read " << nread << " *ELEMENT entries ("
611  << elemTypeName << ") elset="
612  << elsetName << nl;
613  }
614  continue;
615  }
616 
617  //
618  // "*Surface" section
619  //
620  if (upperLine.starts_with("*SURFACE,"))
621  {
622  // Require "NAME=..." on the same line
623  const string elsetName(getIdentifier("NAME", line));
624 
625  // May have "TYPE=..." on the same line.
626  // If missing, default is ELEMENT.
627  const string surfTypeName(getIdentifier("TYPE", line));
628 
629  if
630  (
631  !surfTypeName.empty()
632  && stringOps::upper(surfTypeName) != "ELEMENT"
633  )
634  {
635  Info<< "Reading abaqus surface type "
636  << surfTypeName << " is not implemented" << nl;
637  continue;
638  }
639 
640  // Treat like an element set
641  const label elsetId = addNewElset(elsetName);
642 
643  skipComments(is);
644 
645  nread = readSurfaceElements(is, elsetId);
646 
647  if (verbose_)
648  {
649  InfoErr
650  << "Read " << nread << " *SURFACE entries for "
651  << elsetName << nl;
652  }
653  continue;
654  }
655  }
656 }
657 
658 
660 {
661  // Negative set
662  bitSet select(elemTypes_.size(), false);
663 
664  forAll(elemTypes_, i)
665  {
666  if (!isValidType(elemTypes_[i]) || isSolidType(elemTypes_[i]))
667  {
668  select.set(i);
669  }
670  }
671 
672  if (select.any())
673  {
674  select.flip();
675 
676  inplaceSubset(select, connectivity_);
677  inplaceSubset(select, elemTypes_);
679  inplaceSubset(select, elemIds_);
680  inplaceSubset(select, elsetIds_);
681  }
682 }
683 
684 
686 {
687  if (!nodeIds_.empty())
688  {
689  // Has original 1-based ids
690  //
691  // Need to convert to local (0-based) points
692  // in the order in which we read them
693  // and compact unused values
694 
695  // Could construct a sort order to preserve the original
696  // point order, but that is not likely relevant for anyone.
697 
698 
699  // Which original node ids actually being used by elements?
700 
701  // We may have many ids, but speculate that they are sparse
702  // and have high element numbers.
703 
704  // Use a Map instead of labelList.
705 
706  Map<label> nodeIdRemapping(2*points_.size());
707 
708  // Pass 1: which nodes are being used?
709 
710  for (const labelList& elem : connectivity_)
711  {
712  for (const label origId : elem)
713  {
714  nodeIdRemapping(origId) = 0; // any value
715  }
716  }
717 
718  // Define compact local points, finalize the node id remapping
719 
720  label nPoints = 0;
721  labelList oldToNewLocal(nodeIds_.size(), -1);
722 
723  forAll(nodeIds_, i)
724  {
725  const label origId = nodeIds_[i];
726 
727  if (nodeIdRemapping.found(origId))
728  {
729  oldToNewLocal[i] = nPoints;
730  nodeIdRemapping(origId) = nPoints;
731  ++nPoints;
732  }
733  }
734 
735  // Prune out -1 values (shrinks list)
736  inplaceReorder(oldToNewLocal, points_, true);
737 
738  // Relabel the elements
739 
740  for (labelList& elem : connectivity_)
741  {
742  for (label& id : elem)
743  {
744  id = nodeIdRemapping[id];
745  }
746  }
747 
748  // Done!
749  nodeIds_.clear();
750  }
751  else
752  {
753  // Already numbered (0-based), but perhaps not compacted
754 
755  // Which node ids actually being used by elements?
756  bitSet usedNodeIds(points_.size());
757 
758  for (const labelList& elem : connectivity_)
759  {
760  usedNodeIds.set(elem);
761  }
762 
763  // Compact the numbers
764  labelList oldToNewLocal = invert(points_.size(), usedNodeIds);
765 
766  // Prune out -1 values (shrinks list)
767  inplaceReorder(oldToNewLocal, points_, true);
768 
769 
770  // Renumber non-compact to compact
771  for (labelList& elem : connectivity_)
772  {
773  inplaceRenumber(oldToNewLocal, elem);
774  }
775  }
776 }
777 
778 
780 {
781  for (label& elemId : elemIds_)
782  {
783  renumber0_elemId(elemId);
784  }
785 }
786 
787 
789 (
790  Ostream& os,
791  const UList<point>& points,
792  const scalar scaleFactor
793 )
794 {
795  if (points.empty())
796  {
797  return;
798  }
799 
800  // Set the precision of the points data to 10
801  os.precision(10);
802 
803  // Force decimal point for Fortran input
804  os.setf(std::ios::showpoint);
805 
806  label vertId = 1; // 1-based vertex labels
807 
808  os << "*NODE" << nl;
809  for (const point& p : points)
810  {
811  // Convert [m] -> [mm] etc
812  os << " "
813  << vertId << ", "
814  << (scaleFactor * p.x()) << ','
815  << (scaleFactor * p.y()) << ','
816  << (scaleFactor * p.z()) << nl;
818  ++vertId;
819  }
820 }
821 
822 
824 (
825  const UList<point>& points,
826  const UList<face>& faces,
827  labelList& decompOffsets,
828  DynamicList<face>& decompFaces
829 )
830 {
831  // On-demand face decomposition (triangulation)
832 
833  decompOffsets.resize(faces.size()+1);
834  decompFaces.clear();
835 
836  auto offsetIter = decompOffsets.begin();
837  *offsetIter = 0; // The first offset is always zero
838 
839  for (const face& f : faces)
840  {
841  const label n = f.size();
842 
843  if (n != 3 && n != 4)
844  {
845  // Decompose non-tri/quad into tris
846  f.triangles(points, decompFaces);
847  }
848 
849  // The end offset, which is the next begin offset
850  *(++offsetIter) = decompFaces.size();
851  }
852 
853  return decompFaces.size();
854 }
855 
856 
857 // ************************************************************************* //
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition: word.C:39
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
Input/output streams with (internal or external) character storage.
A line primitive.
Definition: line.H:52
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
messageStream InfoErr
Information stream (stderr output on master, null elsewhere)
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:160
virtual const std::istream & stdStream() const
Const access to underlying std::istream.
Definition: ISstream.H:154
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
IOstream & hex(IOstream &io)
Definition: IOstream.H:545
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
shapeType
Shape-Type - the values are for internal use only!
Definition: ABAQUSCore.H:248
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:489
List< bool > select(const label n, const labelUList &locations)
Construct a selection list of bools (all false) with the given pre-size, subsequently add specified l...
Definition: BitOps.C:134
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
void inplaceRemoveSpace(std::string &s)
Eliminate whitespace inplace.
Definition: stringOps.C:1061
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
void syncState()
Set stream state to match that of the std::istream.
Definition: ISstream.H:183
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:63
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1187
void read(ISstream &is)
Read an abaqus input file.
Definition: ABAQUSCore.C:525
void compact_nodes()
Compact unused points and relabel connectivity.
Definition: ABAQUSCore.C:678
void inplaceSubset(const BoolListType &select, ListType &input, const bool invert=false)
Inplace extract elements of the input list when select is true.
void renumber_elements_1to0()
Renumber elements from 1-based to 0-based.
Definition: ABAQUSCore.C:772
#define checkElemType(Name)
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
Definition: cellModels.C:150
static string getIdentifier(const word &keyword, string &inputLine)
Definition: ABAQUSCore.C:91
dimensionedScalar pos(const dimensionedScalar &ds)
static void writePoints(Ostream &os, const UList< point > &points, const scalar scaleFactor=1.0)
Write &#39;*NODE&#39; header and entries to file, optionally with scaling.
Definition: ABAQUSCore.C:782
static label encodeSolidId(const label id, const label side)
Combine solid element Id and side Id into synthetic face Id.
Definition: ABAQUSCore.H:313
const pointField & points
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
A class for handling words, derived from Foam::string.
Definition: word.H:63
label nPoints
int peek()
Raw, low-level peek function.
Definition: ISstreamI.H:63
static void skipComments(ISstream &iss)
Definition: ABAQUSCore.C:45
static shapeType getElementType(const string &elemTypeName)
Classify named element type (eg, S4R) to known/supported element types.
Definition: ABAQUSCore.C:198
label readElements(ISstream &is, const ABAQUSCore::shapeType shape, const label setId=0)
Read entries within an "*Element" section.
Definition: ABAQUSCore.C:347
label readSurfaceElements(ISstream &is, const label setId=0)
Read elements within an "*Surface" section.
Definition: ABAQUSCore.C:402
static int nPoints(shapeType tag)
The number of points associated with the element type.
Definition: ABAQUSCore.H:273
patchWriters clear()
const faceList & modelFaces() const noexcept
Return a raw list of model faces.
Definition: cellModelI.H:60
static bool appendCsvLabels(const std::string &line, labelUList &elemNodes, label &nodei)
Definition: ABAQUSCore.C:138
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:391
static const string null
An empty string.
Definition: string.H:202
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:817
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:69
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
OBJstream os(runTime.globalPath()/outputName)
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:405
labelList f(nPoints)
static const Map< labelList > & abaqusToFoamFaceAddr()
Face addressing from ABAQUS faces to OpenFOAM faces.
Definition: ABAQUSCore.C:184
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:29
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:51
vector point
Point is a vector.
Definition: point.H:37
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:281
Maps a geometry to a set of cell primitives.
Definition: cellModel.H:72
messageStream Info
Information stream (stdout output on master, null elsewhere)
label n
static Foam::Map< Foam::labelList > abaqusToFoamFaceAddr_
Definition: ABAQUSCore.C:31
label readPoints(ISstream &is)
Read entries within a "*Nodes" section.
Definition: ABAQUSCore.C:310
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
ISstream & get(char &c)
Raw, low-level get character function.
Definition: ISstreamI.H:49
void purge_solids()
Remove non-shell elements and compact the points.
Definition: ABAQUSCore.C:652
Similar to IStringStream but using an externally managed buffer for its input. This allows the input ...
Definition: ISpanStream.H:286
label addNewElset(const std::string &setName)
Add a new element set name or return an existing one.
Definition: ABAQUSCore.C:262
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
A HashTable to objects of type <T> with a label key.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127