Loading...
Searching...
No Matches
abaqusSurfaceWriterImpl.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 "IOmanip.H"
29#include "OFstream.H"
30#include "OSspecific.H"
31
32// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33
34template<class Type>
35Foam::Ostream& Foam::surfaceWriters::abaqusWriter::writeFaceValue
36(
37 Ostream& os,
38 const Type& value,
39 const label elemId
40) const
41{
43 {
44 const label solidId =
46
47 const label sideNum =
49
50 // Element-id: 0-based to 1-based
51 // Side-id: always 1-based
52 os << (solidId + 1) << ", P" << sideNum;
53 }
54 else
55 {
56 // Element-id: 0-based to 1-based
57 os << (elemId + 1) << ", P";
58 }
59
60 os << ", ";
62 {
63 os << value;
64 }
65 else
66 {
67 os << mag(value);
68 }
69 os << nl;
70
71 return os;
72}
73
74
75template<class Type>
76Foam::fileName Foam::surfaceWriters::abaqusWriter::writeTemplate
77(
78 const word& fieldName,
79 const Field<Type>& localValues
80)
81{
82 checkOpen();
83
84 // Field:
85 // 1) rootdir/<TIME>/<field>_surfaceName.inp
86 // 2) rootdir/<field>/surfaceName_<TIME>.inp
87
88 fileName outputFile;
89
90 switch (outputLayout_)
91 {
92 case outputLayoutType::BY_TIME:
93 {
94 outputFile = outputPath_;
95 if (useTimeDir() && !timeName().empty())
96 {
97 // Splice in time-directory
98 outputFile =
99 outputPath_.path() / timeName() / outputPath_.name();
100 }
101
102 // Append <field>_surfaceName
103 outputFile /= fieldName + '_' + outputPath_.name();
104 break;
105 }
106 case outputLayoutType::BY_FIELD:
107 {
108 outputFile = outputPath_ / fieldName / outputPath_.name();
109 if (!timeName().empty())
110 {
111 // Append time information to file name
112 outputFile += '_' + timeName();
113 }
114 break;
115 }
116 }
117 outputFile.ext("inp");
118
119
120 // Implicit geometry merge()
121 tmp<Field<Type>> tfield = adjustField(fieldName, mergeField(localValues));
122
123 if (verbose_)
124 {
125 Info<< " to " << outputFile << endl;
126 }
127
128
129 // const meshedSurf& surf = surface();
130 const meshedSurfRef& surf = adjustSurface();
131
132 if (UPstream::master() || !parallel_)
133 {
134 const auto& values = tfield();
135
136 if (!isDir(outputFile.path()))
137 {
138 mkDir(outputFile.path());
139 }
140
141 // const scalar timeValue(0);
142
143
144 // Additional bookkeeping for decomposing non tri/quad
145 labelList decompOffsets;
146 DynamicList<face> decompFaces;
147
148
149 OFstream os(outputFile);
150
151 if (noGeometry_ || wroteGeom_)
152 {
153 // Geometry already written (or suppressed)
154 // - still need decomposition information
155
157 (
158 surf.points(),
159 surf.faces(),
160 decompOffsets,
161 decompFaces
162 );
163 }
164 else
165 {
166 // Write geometry (separate file)
167
168 OFstream osGeom(outputFile.lessExt().ext("abq"));
169 writeGeometry(osGeom, surf, decompOffsets, decompFaces);
170 }
171
172 // Write field
173 // *DLOAD
174 // Element-based: // elemId, P, 1000
175 // Surface-based: // elemId, P4, 1000
176
177 os << "**" << nl
178 << "** field = " << fieldName << nl
179 << "** type = " << pTraits<Type>::typeName << nl;
180
181 if (useTimeDir() && !timeName().empty())
182 {
183 os << "** time = " << timeName() << nl;
184 }
185
186 os << "**" << nl
187 << "*DLOAD" << nl;
188
189
190 // Regular (undecomposed) faces
191 const faceList& faces = surf.faces();
192 const labelList& elemIds = surf.faceIds();
193
194 // Possible to use faceIds?
195 const bool useOrigFaceIds =
196 (
197 elemIds.size() == faces.size()
198 && decompFaces.empty()
199 );
200
201
202 label elemId = 0;
203
204 if (this->isPointData())
205 {
206 forAll(faces, facei)
207 {
208 if (useOrigFaceIds)
209 {
210 // When available and not decomposed
211 elemId = elemIds[facei];
212 }
213
214 const label beginElemId = elemId;
215
216 // Any face decomposition
217 for
218 (
219 label decompi = decompOffsets[facei];
220 decompi < decompOffsets[facei+1];
221 ++decompi
222 )
223 {
224 const face& f = decompFaces[decompi];
225
226 Type v = Zero;
227 for (const label verti : f)
228 {
229 v += values[verti];
230 }
231 v /= f.size();
232
233 writeFaceValue(os, v, elemId); // 0-based
234 ++elemId;
235 }
236
237
238 // Face not decomposed
239 if (beginElemId == elemId)
240 {
241 const face& f = faces[facei];
242
243 Type v = Zero;
244 for (const label verti : f)
245 {
246 v += values[verti];
247 }
248 v /= f.size();
249
250 writeFaceValue(os, v, elemId); // 0-based
251 ++elemId;
252 }
253 }
254 }
255 else
256 {
257 auto valIter = values.cbegin();
258
259 forAll(faces, facei)
260 {
261 if (useOrigFaceIds)
262 {
263 // When available and not decomposed
264 elemId = elemIds[facei];
265 }
266
267 const Type v(*valIter);
268 ++valIter;
269
270 label nValues =
271 max
272 (
273 label(1),
274 (decompOffsets[facei+1] - decompOffsets[facei])
275 );
276
277 while (nValues--)
278 {
279 writeFaceValue(os, v, elemId); // 0-based
280 ++elemId;
281 }
282 }
283 }
284
285 os << "**" << nl
286 << "**" << nl;
287 }
288
289 wroteGeom_ = true;
290 return outputFile;
291}
292
293
294// ************************************************************************* //
Istream and Ostream manipulators taking arguments.
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
writer writeGeometry()
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
Definition OFstream.H:75
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
bool wroteGeom_
Track if geometry has been written since the last open.
bool useTimeDir() const noexcept
Should a time directory be spliced into the output path?
void checkOpen() const
Verify that the outputPath_ has been set or FatalError.
bool empty() const
Writer is not associated with content.
bool verbose_
Additional output verbosity.
fileName outputPath_
The full output directory and file (coords) name.
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
static label decodeSolidSideNum(const label combinedId)
Entangle solid side id from synthetic face Id Synthesize faceId from solid element Id and sideId.
Definition ABAQUSCore.H:335
static bool isEncodedSolidId(const label combinedId)
Is a combined (synthetic) face Id?
Definition ABAQUSCore.H:305
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
static label decodeSolidElementId(const label combinedId)
Entangle solid element id from synthetic face Id.
Definition ABAQUSCore.H:321
A class for handling file names.
Definition fileName.H:75
fileName lessExt() const
Return file name without extension (part before last .).
Definition fileNameI.H:238
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
Implements a meshed surface by referencing another meshed surface or faces/points components.
virtual const pointField & points() const
The points used for the surface.
virtual const labelList & faceIds() const
Per-face identifier (eg, element Id).
virtual const faceList & faces() const
The faces used for the surface.
A traits class, which is primarily used for primitives and vector-space.
Definition pTraits.H:64
A class for managing temporary objects.
Definition tmp.H:75
A class for handling words, derived from Foam::string.
Definition word.H:66
OBJstream os(runTime.globalPath()/outputName)
word timeName
Definition getTimeIndex.H:3
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition HashOps.H:164
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
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
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
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