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 -------------------------------------------------------------------------------
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 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 const Foam::Enum
36 <
38 >
40 ({
41  { fieldFormat::SHORT, "short" },
42  { fieldFormat::LONG, "long" },
43  { fieldFormat::FREE, "free" },
44 });
45 
46 
47 const Foam::Enum
48 <
50 >
52 ({
53  { loadFormat::PLOAD2, "PLOAD2" },
54  { loadFormat::PLOAD4, "PLOAD4" },
55 });
56 
57 
58 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
59 
60 namespace Foam
61 {
62 
63 template<class Type>
64 static 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 
75 Foam::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,
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 {
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 // ************************************************************************* //
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:70
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:132
loadFormat
Output load format.
Definition: NASCore.H:75
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
static const Enum< loadFormat > loadFormatNames
Selection names for the NASTRAN file field formats.
Definition: NASCore.H:84
int readInt(Istream &is)
Read int from stream.
Definition: intIO.C:73
fieldFormat
File field formats.
Definition: NASCore.H:60
static void putValue(Ostream &os, const Type &value, const int width)
Definition: NASCore.C:57
dimensionedScalar pos(const dimensionedScalar &ds)
static void setPrecision(Ostream &os, const fieldFormat format)
Set output stream precision and format flags.
Definition: NASCore.C:139
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
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:115
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:68
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:321
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:99
static void writeCoord(Ostream &os, const point &p, const label pointId, const fieldFormat format)
Write a GRID point.
Definition: NASCore.C:207
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
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:194
OBJstream os(runTime.globalPath()/outputName)
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:389
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:68
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...
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:607
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:273
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:173
IOstream & scientific(IOstream &io)
Definition: IOstream.H:563
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 ...