abaqusSurfaceWriter.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 "abaqusSurfaceWriter.H"
29 #include "ABAQUSCore.H"
30 #include "IOmanip.H"
31 #include "ListOps.H"
32 #include "OSspecific.H"
33 #include "surfaceWriterMethods.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40 namespace surfaceWriters
41 {
45 }
46 }
47 
48 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49 
50 // Field writing implementation
52 
53 // Field writing methods
55 
56 
57 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
58 
59 namespace Foam
60 {
61 
62 // Write connectivity as CSV list
63 inline static void writeConnectivity
64 (
65  Ostream& os,
66  const label elemId,
67  const labelUList& elem
68 )
69 {
70  os << " " << elemId;
71 
72  for (const label vert : elem)
73  {
74  os << ", " << (vert + 1);
75  }
76 
77  os << nl;
78 }
79 
80 } // End namespace Foam
81 
82 
83 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
84 
85 void Foam::surfaceWriters::abaqusWriter::writeFace
86 (
87  Ostream& os,
88  const labelUList& f,
89  const label elemId,
90  const label propId,
91  bool header
92 ) const
93 {
94  // Only called with 3 or 4 points!
95 
96  if (header)
97  {
98  os << "*ELEMENT, TYPE=S" << f.size();
99 
100  if (propId >= 0)
101  {
102  os << ", ELSET=_" << propId;
103  }
104 
105  os << nl;
106  }
107 
108  writeConnectivity(os, elemId, f);
109 }
110 
111 
112 void Foam::surfaceWriters::abaqusWriter::writeGeometry
113 (
114  Ostream& os,
115  const meshedSurf& surf,
116  labelList& decompOffsets,
117  DynamicList<face>& decompFaces
118 ) const
119 {
120  const pointField& points = surf.points();
121  const faceList& faces = surf.faces();
122  const labelList& zones = surf.zoneIds();
123  const labelList& elemIds = surf.faceIds();
124 
125  // Possible to use faceIds?
126  bool useOrigFaceIds =
127  (
128  elemIds.size() == faces.size()
129  && !ListOps::found(elemIds, lessOp1<label>(0))
130  );
131 
132  if (useOrigFaceIds)
133  {
134  // Not possible with on-the-fly face decomposition
135  for (const auto& f : faces)
136  {
137  if (f.size() > 4)
138  {
139  useOrigFaceIds = false;
140  break;
141  }
142  }
143  }
144 
145 
146  os << "** Geometry" << nl;
147 
148  os << nl
149  << "**" << nl
150  << "** Points" << nl
151  << "**" << nl;
152 
154 
155 
156  // Write faces, with on-the-fly decomposition (triangulation)
157  decompOffsets.resize(faces.size()+1);
158  decompFaces.clear();
159 
160  decompOffsets[0] = 0; // The first offset is always zero
161 
162  os << "**" << nl
163  << "** Faces" << nl
164  << "**" << nl;
165 
166  // Simple tracking for change of element type/set
167  labelPair prevOutput(-1, -1);
168 
169  label elemId = 0; // The element-id
170  forAll(faces, facei)
171  {
172  const face& f = faces[facei];
173 
174  if (useOrigFaceIds)
175  {
176  // When available and not decomposed
177  elemId = elemIds[facei];
178  }
179 
180  // 1-offset for PID
181  const label propId = 1 + (facei < zones.size() ? zones[facei] : 0);
182 
183  const label n = f.size();
184 
185  bool header =
186  (prevOutput.first() != n || prevOutput.second() != propId);
187 
188  if (header)
189  {
190  // Update values
191  prevOutput.first() = n;
192  prevOutput.second() = propId;
193  }
194 
195  if (n == 3 || n == 4)
196  {
197  writeFace(os, f, ++elemId, propId, header);
198  }
199  else
200  {
201  // Decompose into tris
202  prevOutput.first() = 3;
203 
204  f.triangles(points, decompFaces);
205 
206  for
207  (
208  label decompi = decompOffsets[facei];
209  decompi < decompFaces.size();
210  ++decompi
211  )
212  {
213  writeFace
214  (
215  os,
216  decompFaces[decompi],
217  ++elemId,
218  propId,
219  header
220  );
221 
222  header = false;
223  }
224  }
225 
226  // The end offset, which is the next begin offset
227  decompOffsets[facei+1] = decompFaces.size();
228  }
229 
230  os << "**" << nl
231  << "**" << nl;
232 }
233 
234 
235 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
236 
238 :
239  surfaceWriter(),
240  geometryScale_(1),
241  fieldScale_(),
242  noGeometry_(false),
243  outputLayout_(outputLayoutType::BY_FIELD)
244 {}
245 
246 
248 (
249  const dictionary& options
250 )
251 :
252  surfaceWriter(options),
253  geometryScale_(options.getOrDefault<scalar>("scale", 1)),
254  fieldScale_(options.subOrEmptyDict("fieldScale")),
255  noGeometry_(options.getOrDefault("noGeometry", false)),
256  outputLayout_(outputLayoutType::BY_FIELD)
257 {}
258 
259 
261 (
262  const meshedSurf& surf,
263  const fileName& outputPath,
264  bool parallel,
265  const dictionary& options
266 )
267 :
268  abaqusWriter(options)
269 {
270  open(surf, outputPath, parallel);
271 }
272 
273 
275 (
276  const pointField& points,
277  const faceList& faces,
278  const fileName& outputPath,
279  bool parallel,
280  const dictionary& options
281 )
282 :
283  abaqusWriter(options)
284 {
285  open(points, faces, outputPath, parallel);
286 }
287 
288 
289 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
290 
292 {
293  checkOpen();
294 
295  // Geometry:
296  // 1) rootdir/<TIME>/surfaceName.abq
297  // 2) rootdir/geometry/surfaceName_<TIME>.abq
298 
299  fileName outputFile;
300 
301  switch (outputLayout_)
302  {
303  case outputLayoutType::BY_TIME:
304  {
305  outputFile = outputPath_;
306  if (useTimeDir() && !timeName().empty())
307  {
308  // Splice in time-directory
309  outputFile =
310  outputPath_.path() / timeName() / outputPath_.name();
311  }
312  break;
313  }
314  case outputLayoutType::BY_FIELD:
315  {
316  outputFile = outputPath_ / "geometry" / outputPath_.name();
317  if (!timeName().empty())
318  {
319  // Append time information to file name
320  outputFile += '_' + timeName();
321  }
322  break;
323  }
324  }
325  outputFile.ext("abq");
326 
327  if (verbose_)
328  {
329  Info<< "Writing abaqus geometry to " << outputFile << endl;
330  }
331 
332 
333  const meshedSurf& surf = surface();
334 
335  if (Pstream::master() || !parallel_)
336  {
337  if (!isDir(outputFile.path()))
338  {
339  mkDir(outputFile.path());
340  }
341 
342  OFstream os(outputFile);
343 
344  labelList decompOffsets;
345  DynamicList<face> decompFaces;
346 
347  writeGeometry(os, surf, decompOffsets, decompFaces);
348  }
349 
350  wroteGeom_ = true;
351  return outputFile;
352 }
353 
354 
355 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
abaqusSurfaceWriter.H
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::surfaceWriter
Base class for surface writers.
Definition: surfaceWriter.H:114
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::surfaceWriters::defineTypeName
defineTypeName(abaqusWriter)
Foam::fileName::path
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:176
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::writeConnectivity
static void writeConnectivity(Ostream &os, const label elemId, const labelUList &elem)
Definition: abaqusSurfaceWriter.C:64
Foam::fileName::name
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:199
Foam::meshedSurf
Abstract definition of a meshed surface defined by faces and points.
Definition: meshedSurf.H:49
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
surfaceWriterMethods.H
Convenience macros for instantiating surfaceWriter methods.
writeGeometry
writer writeGeometry()
defineSurfaceWriterWriteFields
defineSurfaceWriterWriteFields(Foam::surfaceWriters::abaqusWriter)
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::labelPair
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:54
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::surfaceWriters::addToRunTimeSelectionTable
addToRunTimeSelectionTable(surfaceWriter, abaqusWriter, word)
Foam::Field< vector >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::surfaceWriters::abaqusWriter::write
virtual fileName write()
Write surface geometry to file.
Definition: abaqusSurfaceWriter.C:291
IOmanip.H
Istream and Ostream manipulators taking arguments.
timeName
word timeName
Definition: getTimeIndex.H:3
abaqusSurfaceWriterImpl.C
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::surfaceWriters::abaqusWriter::abaqusWriter
abaqusWriter()
Default construct.
Definition: abaqusSurfaceWriter.C:237
os
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::fileName::ext
word ext() const
Return file name extension (part after last .)
Definition: fileNameI.H:218
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::dictionary::subOrEmptyDict
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Definition: dictionary.C:540
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::List< face >
Foam::UList< label >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::ListOps::found
bool found(const ListType &input, const UnaryPredicate &pred, const label start=0)
True if there is a value in the list that satisfies the predicate.
Definition: ListOpsTemplates.C:1156
ABAQUSCore.H
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:788
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
Foam::isDir
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:643
Foam::surfaceWriters::abaqusWriter
A surface writer for the ABAQUS file format - both surface mesh and fields.
Definition: abaqusSurfaceWriter.H:123