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