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-2023 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 "NASCore.H"
29 #include "IOmanip.H"
30 #include "Ostream.H"
31 #include "parsing.H"
32 #include "defineDebugSwitch.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 namespace fileFormats
39 {
40  defineDebugSwitchWithName(NASCore, "nastran.debug", 0);
42  (
43  NASCore, Nastran, "nastran.debug"
44  );
45 }
46 }
47 
48 
49 const Foam::Enum
50 <
52 >
54 ({
55  { fieldFormat::SHORT, "short" },
56  { fieldFormat::LONG, "long" },
57  { fieldFormat::FREE, "free" },
58 });
59 
60 
61 const Foam::Enum
62 <
64 >
66 ({
67  { loadFormat::PLOAD2, "PLOAD2" },
68  { loadFormat::PLOAD4, "PLOAD4" },
69 });
70 
71 
72 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
73 
74 namespace Foam
75 {
76 
77 template<class Type>
78 static inline void putValue(Ostream& os, const Type& value, const int width)
79 {
80  if (width) os << setw(width);
81  os << value;
82 }
83 
84 } // End namespace Foam
85 
86 
87 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
88 
89 Foam::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,
140 )
141 {
142  const auto beg = pos;
143  const auto end = str.find(',', pos);
144 
145  if (end == std::string::npos)
146  {
147  pos = beg + len; // Continue after field width
148  }
149  else
150  {
151  len = (end - beg); // Efffective width
152  pos = end + 1; // Continue after comma
153  }
154 
155  return str.substr(beg, len);
156 }
157 
158 
160 (
161  Ostream& os,
162  const fieldFormat format
163 )
164 {
166 
167  // Capitalise the E marker
168  os.setf(std::ios_base::uppercase);
169 
170  const label offset = 7;
171 
172  label prec = 16 - offset;
173  switch (format)
174  {
175  case fieldFormat::SHORT :
176  {
177  prec = 8 - offset;
178  break;
179  }
180 
181  case fieldFormat::LONG :
182  case fieldFormat::FREE :
183  {
184  prec = 16 - offset;
185  break;
186  }
187  }
188 
189  os.precision(prec);
190 }
191 
192 
194 (
195  Ostream& os,
196  const word& keyword,
197  const fieldFormat format
198 )
199 {
200  os.setf(std::ios_base::left);
201 
202  switch (format)
203  {
204  case fieldFormat::SHORT :
205  {
206  os << setw(8) << keyword;
207  break;
208  }
209  case fieldFormat::LONG :
210  {
211  os << setw(8) << word(keyword + '*');
212  break;
213  }
214  case fieldFormat::FREE :
215  {
216  os << keyword;
217  break;
218  }
219  }
220 
221  os.unsetf(std::ios_base::left);
222 
223  return os;
224 }
225 
226 
228 (
229  Ostream& os,
230  const point& p,
231  const label pointId, // zero-based
232  const fieldFormat format
233 )
234 {
235  // Field width (SHORT, LONG formats)
236  const int width =
237  (
238  format == fieldFormat::SHORT ? 8
239  : format == fieldFormat::LONG ? 16
240  : 0
241  );
242 
243  // Separator char (FREE format)
244  const char sep = (format == fieldFormat::FREE ? ',' : '\0');
245 
246 
247  // Fixed short/long formats:
248  // 1 GRID
249  // 2 ID : point ID - requires starting index of 1
250  // 3 CP : coordinate system ID (blank)
251  // 4 X1 : point x coordinate
252  // 5 X2 : point x coordinate
253  // 6 X3 : point x coordinate
254  // 7 CD : coordinate system for displacements (blank)
255  // 8 PS : single point constraints (blank)
256  // 9 SEID : super-element ID
257 
258  writeKeyword(os, "GRID", format);
259  if (sep) os << sep;
260 
261  os.setf(std::ios_base::right);
262 
263  // Point ID (from 0-based to 1-based)
264  putValue(os, (pointId+1), width);
265  if (sep) os << sep;
266 
267  // Coordinate system ID (blank)
268  putValue(os, "", width);
269  if (sep) os << sep;
270 
271  putValue(os, p.x(), width);
272  if (sep) os << sep;
273 
274  putValue(os, p.y(), width);
275  if (sep) os << sep;
276 
277  if (format == fieldFormat::LONG)
278  {
279  // Continuation
280  os.unsetf(std::ios_base::right);
281  os << nl;
282  writeKeyword(os, "", format);
283  os.setf(std::ios_base::right);
284  }
285 
286  putValue(os, p.z(), width);
287  os << nl;
288 
289  os.unsetf(std::ios_base::right);
290 }
291 
292 
294 (
295  const UList<point>& points,
296  const UList<face>& faces,
297  labelList& decompOffsets,
298  DynamicList<face>& decompFaces
299 )
300 {
301  // On-demand face decomposition (triangulation)
302 
303  decompOffsets.resize(faces.size()+1);
304  decompFaces.clear();
305 
306  auto offsetIter = decompOffsets.begin();
307  *offsetIter = 0; // The first offset is always zero
308 
309  for (const face& f : faces)
310  {
311  const label n = f.size();
312 
313  if (n != 3 && n != 4)
314  {
315  // Decompose non-tri/quad into tris
316  f.triangles(points, decompFaces);
317  }
318 
319  // The end offset, which is the next begin offset
320  *(++offsetIter) = decompFaces.size();
321  }
322 
323  return decompFaces.size();
324 }
325 
326 
327 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
static const Enum< fieldFormat > fieldFormatNames
Selection names for the NASTRAN file field formats.
Definition: NASCore.H:78
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:153
loadFormat
Output load format.
Definition: NASCore.H:83
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
static const Enum< loadFormat > loadFormatNames
Selection names for the NASTRAN file field formats.
Definition: NASCore.H:92
int readInt(Istream &is)
Read int from stream.
Definition: intIO.C:73
defineDebugSwitchWithName(NASCore, "nastran.debug", 0)
fieldFormat
File field formats.
Definition: NASCore.H:68
static void putValue(Ostream &os, const Type &value, const int width)
Definition: NASCore.C:71
dimensionedScalar pos(const dimensionedScalar &ds)
static void setPrecision(Ostream &os, const fieldFormat format)
Set output stream precision and format flags.
Definition: NASCore.C:153
const pointField & points
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
registerDebugSwitchWithName(NASCore, Nastran, "nastran.debug")
A class for handling words, derived from Foam::string.
Definition: word.H:63
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:129
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:67
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:392
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:105
static void writeCoord(Ostream &os, const point &p, const label pointId, const fieldFormat format)
Write a GRID point.
Definition: NASCore.C:221
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
Istream and Ostream manipulators taking arguments.
General parsing error.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:201
OBJstream os(runTime.globalPath()/outputName)
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:405
labelList f(nPoints)
static scalar readNasScalar(const std::string &str)
Extract numbers from things like "-2.358-8" (same as "-2.358e-8")
Definition: NASCore.C:82
word format(conversionProperties.get< word >("format"))
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: error.H:64
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:637
Macro definitions for debug switches.
bool isspace(char c) noexcept
Test for whitespace (C-locale)
Definition: char.H:69
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:287
label n
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
volScalarField & p
static Ostream & writeKeyword(Ostream &os, const word &keyword, const fieldFormat format)
Write initial keyword (eg, &#39;GRID&#39; or &#39;GRID*&#39;) followed by the requisite number of spaces for the fiel...
Definition: NASCore.C:187
IOstream & scientific(IOstream &io)
Definition: IOstream.H:578
Namespace for OpenFOAM.
const Foam::Enum< errorType > errorNames
Strings corresponding to the errorType.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...