Loading...
Searching...
No Matches
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-2022 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
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"
36// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38namespace Foam
39{
40namespace surfaceWriters
41{
45}
46}
47
48// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49
50// Field writing implementation
52
53// Field writing methods
55
57// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
58
59namespace Foam
60{
61
62// Write connectivity as CSV list
63inline 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
85void 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
112void 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
240 noGeometry_(false),
241 outputLayout_(outputLayoutType::BY_FIELD)
242{}
243
244
246(
247 const dictionary& options
248)
250 surfaceWriter(options),
251 noGeometry_(options.getOrDefault("noGeometry", false)),
252 outputLayout_(outputLayoutType::BY_FIELD)
253{}
254
255
257(
258 const meshedSurf& surf,
259 const fileName& outputPath,
260 bool parallel,
261 const dictionary& options
262)
264 abaqusWriter(options)
265{
266 open(surf, outputPath, parallel);
267}
268
269
271(
272 const pointField& points,
273 const faceList& faces,
274 const fileName& outputPath,
275 bool parallel,
276 const dictionary& options
277)
278:
279 abaqusWriter(options)
280{
281 open(points, faces, outputPath, parallel);
282}
283
284
285// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
286
288{
289 checkOpen();
290
291 // Geometry:
292 // 1) rootdir/<TIME>/surfaceName.abq
293 // 2) rootdir/geometry/surfaceName_<TIME>.abq
294
295 fileName outputFile;
296
297 switch (outputLayout_)
298 {
299 case outputLayoutType::BY_TIME:
300 {
301 outputFile = outputPath_;
302 if (useTimeDir() && !timeName().empty())
303 {
304 // Splice in time-directory
305 outputFile =
306 outputPath_.path() / timeName() / outputPath_.name();
307 }
308 break;
309 }
310 case outputLayoutType::BY_FIELD:
311 {
312 outputFile = outputPath_ / "geometry" / outputPath_.name();
313 if (!timeName().empty())
314 {
315 // Append time information to file name
316 outputFile += '_' + timeName();
317 }
318 break;
319 }
320 }
321 outputFile.ext("abq");
322
323 if (verbose_)
324 {
325 Info<< "Writing abaqus geometry to " << outputFile << endl;
326 }
327
328
329 // const meshedSurf& surf = surface();
330 const meshedSurfRef& surf = adjustSurface();
331
332 if (UPstream::master() || !parallel_)
333 {
334 if (!isDir(outputFile.path()))
335 {
336 mkDir(outputFile.path());
337 }
338
339 OFstream os(outputFile);
340
341 labelList decompOffsets;
342 DynamicList<face> decompFaces;
343
344 writeGeometry(os, surf, decompOffsets, decompFaces);
345 }
346
347 wroteGeom_ = true;
348 return outputFile;
349}
350
351
352// ************************************************************************* //
Istream and Ostream manipulators taking arguments.
Various functions to operate on Lists.
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
label n
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
writer writeGeometry()
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
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:782
A class for handling file names.
Definition fileName.H:75
word ext() const
Return file name extension (part after last .).
Definition fileNameI.H:211
static std::string path(const std::string &str)
Return directory path name (part before last /).
Definition fileNameI.H:169
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition fileNameI.H:192
Abstract definition of a meshed surface defined by faces and points.
Definition meshedSurf.H:44
Base class for surface writers.
surfaceWriter()
Default construct.
virtual void open(const fileName &outputPath)
Open for output on specified path, using existing surface.
A surface writer for the ABAQUS file format - both surface mesh and fields.
virtual fileName write()
Write surface geometry to file.
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeName(Type)
Define the typeName.
Definition className.H:113
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
word timeName
Definition getTimeIndex.H:3
bool found(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as found_if.
Definition ListOps.H:886
Namespace for surface writers.
Namespace for OpenFOAM.
Pair< label > labelPair
A pair of labels.
Definition Pair.H:54
List< label > labelList
A List of labels.
Definition List.H:62
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition POSIX.C:616
messageStream Info
Information stream (stdout output on master, null elsewhere).
List< face > faceList
List of faces.
Definition faceListFwd.H:41
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
static void writeConnectivity(Ostream &os, const label elemId, const labelUList &elem)
vectorField pointField
pointField is a vectorField.
UList< label > labelUList
A UList of labels.
Definition UList.H:75
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition POSIX.C:862
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Convenience macros for instantiating surfaceWriter methods.
#define defineSurfaceWriterWriteFields(ThisClass)