Loading...
Searching...
No Matches
NASCore.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) 2017-2024 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 "NASCore.H"
29#include "IOmanip.H"
30#include "Ostream.H"
31#include "parsing.H"
32#include "defineDebugSwitch.H"
34// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35
36namespace Foam
37{
38namespace fileFormats
39{
40 defineDebugSwitchWithName(NASCore, "nastran.debug", 0);
42 (
43 NASCore, Nastran, "nastran.debug"
44 );
45}
46}
47
48
49const Foam::Enum
50<
52>
54({
55 { fieldFormat::SHORT, "short" },
56 { fieldFormat::LONG, "long" },
57 { fieldFormat::FREE, "free" },
58});
59
60
61const Foam::Enum
62<
64>
66({
67 { loadFormat::PLOAD2, "PLOAD2" },
68 { loadFormat::PLOAD4, "PLOAD4" },
69});
70
72// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
73
74namespace Foam
75{
76
77template<class Type>
78static inline void putValue(Ostream& os, const Type& value, const int width)
79{
80 if (width) os << setw(width);
81 os << value;
83
84} // End namespace Foam
85
86
87// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
88
89Foam::scalar Foam::fileFormats::NASCore::readNasScalar(const std::string& str)
90{
91 const auto signPos = str.find_last_of("+-");
92
93 if
94 (
95 signPos == std::string::npos
96 || signPos == 0
97 || str[signPos-1] == 'E' || str[signPos-1] == 'e'
98 || isspace(str[signPos-1])
99 )
100 {
101 // A normal number format
102 return readScalar(str);
103 }
104
105
106 // Nastran compact number format.
107 // Eg, "1234-2" instead of "1234E-2"
108
109 scalar value = 0;
110 int exponent = 0; // Any integer
111
112 if
113 (
114 readScalar(str.substr(0, signPos), value) // Mantissa
115 && readInt(str.substr(signPos), exponent) // Exponent (with sign)
116 )
117 {
118 // Note: this does not catch underflow/overflow
119 // (especially when scalar is a float)
120 value *= ::pow(10, exponent);
121 }
122 else
123 {
124 FatalIOErrorInFunction("unknown")
126 << exit(FatalIOError);
127
128 value = 0;
129 }
130
131 return value;
132}
133
134
136(
137 const std::string& str,
138 std::string::size_type& pos,
139 const std::string::size_type width,
140 const bool free_format
141)
142{
143 const auto beg = pos;
144 const auto end = str.find(',', pos);
145
146 if (end == std::string::npos)
147 {
148 if (free_format)
149 {
150 // Nothing left
151 pos = str.size();
152 return str.substr(beg);
153 }
154
155 // Fixed format - continue after field width
156 pos = beg + width;
157 return str.substr(beg, width);
158 }
159 else
160 {
161 // Free format - continue after comma
162 pos = end + 1;
163 return str.substr(beg, (end - beg));
164 }
165}
166
167
169(
170 Ostream& os,
171 const fieldFormat format
172)
173{
174 os.setf(std::ios_base::scientific);
175
176 // Capitalise the E marker
177 os.setf(std::ios_base::uppercase);
178
179 const label offset = 7;
180
181 label prec = 16 - offset;
182 switch (format)
183 {
184 case fieldFormat::SHORT :
185 {
186 prec = 8 - offset;
187 break;
188 }
189
190 case fieldFormat::LONG :
191 case fieldFormat::FREE :
192 {
193 prec = 16 - offset;
194 break;
196 }
197
198 os.precision(prec);
199}
200
201
203(
204 Ostream& os,
205 const word& keyword,
206 const fieldFormat format
207)
208{
209 os.setf(std::ios_base::left);
210
211 switch (format)
212 {
213 case fieldFormat::SHORT :
214 {
215 os << setw(8) << keyword;
216 break;
217 }
218 case fieldFormat::LONG :
219 {
220 os << setw(8) << word(keyword + '*');
221 break;
222 }
223 case fieldFormat::FREE :
224 {
225 os << keyword;
226 break;
227 }
228 }
230 os.unsetf(std::ios_base::left);
231
232 return os;
233}
234
235
237(
238 Ostream& os,
239 const point& p,
240 const label pointId, // zero-based
241 const fieldFormat format
242)
243{
244 // Field width (SHORT, LONG formats)
245 const int width =
246 (
247 format == fieldFormat::SHORT ? 8
248 : format == fieldFormat::LONG ? 16
249 : 0
250 );
251
252 // Separator char (FREE format)
253 const char sep = (format == fieldFormat::FREE ? ',' : '\0');
254
255
256 // Fixed short/long formats:
257 // 1 GRID
258 // 2 ID : point ID - requires starting index of 1
259 // 3 CP : coordinate system ID (blank)
260 // 4 X1 : point x coordinate
261 // 5 X2 : point y coordinate
262 // 6 X3 : point z coordinate
263 // 7 CD : coordinate system for displacements (blank)
264 // 8 PS : single point constraints (blank)
265 // 9 SEID : super-element ID
266
267 writeKeyword(os, "GRID", format);
268 if (sep) os << sep;
269
270 os.setf(std::ios_base::right);
271
272 // Point ID (from 0-based to 1-based)
273 putValue(os, (pointId+1), width);
274 if (sep) os << sep;
275
276 // Coordinate system ID (blank)
277 putValue(os, "", width);
278 if (sep) os << sep;
279
280 putValue(os, p.x(), width);
281 if (sep) os << sep;
282
283 putValue(os, p.y(), width);
284 if (sep) os << sep;
285
286 if (format == fieldFormat::LONG)
287 {
288 // Continuation
289 os.unsetf(std::ios_base::right);
290 os << nl;
291 writeKeyword(os, "", format);
292 os.setf(std::ios_base::right);
293 }
294
295 putValue(os, p.z(), width);
296 os << nl;
297
298 os.unsetf(std::ios_base::right);
299}
300
301
303(
304 const UList<point>& points,
305 const UList<face>& faces,
306 labelList& decompOffsets,
307 DynamicList<face>& decompFaces
308)
309{
310 // On-demand face decomposition (triangulation)
311
312 decompOffsets.resize(faces.size()+1);
313 decompFaces.clear();
314
315 auto offsetIter = decompOffsets.begin();
316 *offsetIter = 0; // The first offset is always zero
317
318 for (const face& f : faces)
319 {
320 const label n = f.size();
321
322 if (n != 3 && n != 4)
323 {
324 // Decompose non-tri/quad into tris
325 f.triangles(points, decompFaces);
326 }
327
328 // The end offset, which is the next begin offset
329 *(++offsetIter) = decompFaces.size();
330 }
331
332 return decompFaces.size();
333}
334
335
336// ************************************************************************* //
Istream and Ostream manipulators taking arguments.
label n
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition Enum.H:57
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Core routines used when reading/writing NASTRAN files.
Definition NASCore.H:53
static Ostream & writeKeyword(Ostream &os, const word &keyword, const fieldFormat format)
Write initial keyword (eg, 'GRID' or 'GRID*') followed by the requisite number of spaces for the fiel...
Definition NASCore.C:196
static void writeCoord(Ostream &os, const point &p, const label pointId, const fieldFormat format)
Write a GRID point.
Definition NASCore.C:230
static void setPrecision(Ostream &os, const fieldFormat format)
Set output stream precision and format flags.
Definition NASCore.C:162
fieldFormat
File field formats.
Definition NASCore.H:68
@ SHORT
Short format (field width = 8).
Definition NASCore.H:69
@ LONG
Long format (field width = 16).
Definition NASCore.H:70
@ FREE
Free format (comma-separated fields).
Definition NASCore.H:71
static std::string nextNasField(const std::string &str, std::string::size_type &pos, const std::string::size_type width, const bool free_format=false)
A std::string::substr() variant to handle fixed-format and free-format NASTRAN.
Definition NASCore.C:129
static const Enum< loadFormat > loadFormatNames
Selection names for the NASTRAN load formats.
Definition NASCore.H:91
static const Enum< fieldFormat > fieldFormatNames
Selection names for the NASTRAN file field formats.
Definition NASCore.H:77
loadFormat
Output load format.
Definition NASCore.H:83
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 NASCore.C:296
static scalar readNasScalar(const std::string &str)
Extract numbers from things like "-2.358-8" (same as "-2.358e-8").
Definition NASCore.C:82
A class for handling words, derived from Foam::string.
Definition word.H:66
volScalarField & p
Macro definitions for debug switches.
#define registerDebugSwitchWithName(Type, Tag, Name)
Define the debug information, lookup as Name.
#define defineDebugSwitchWithName(Type, Name, Value)
Define the debug information, lookup as Name.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
Namespace to isolate specifics for file formats, and some common utilities.
@ GENERAL
General parsing error.
Definition parsing.H:58
const Foam::Enum< errorType > errorNames
Strings corresponding to the errorType.
Namespace for OpenFOAM.
dimensionedScalar pos(const dimensionedScalar &ds)
List< label > labelList
A List of labels.
Definition List.H:62
constexpr bool isspace(char c) noexcept
Test for whitespace (C-locale only).
Definition char.H:77
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Omanip< int > setw(const int i)
Definition IOmanip.H:199
int readInt(Istream &is)
Read int from stream.
Definition intIO.C:73
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
vector point
Point is a vector.
Definition point.H:37
static void putValue(Ostream &os, const Type &value, const int width)
Definition NASCore.C:71
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
word format(conversionProperties.get< word >("format"))
labelList f(nPoints)