nastranSurfaceWriter.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2012-2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "nastranSurfaceWriter.H"
27 #include "IOmanip.H"
28 #include "Tuple2.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35  makeSurfaceWriterType(nastranSurfaceWriter);
36  addToRunTimeSelectionTable(surfaceWriter, nastranSurfaceWriter, wordDict);
37 
38  // create write methods
39  defineSurfaceWriterWriteFields(nastranSurfaceWriter);
40 
41  template<>
43  {
44  "short",
45  "long",
46  "free"
47  };
48 
51 }
52 
53 
54 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
55 
56 void Foam::nastranSurfaceWriter::formatOS(OFstream& os) const
57 {
59 
60  // capitalize the E marker
61  os.setf(ios_base::uppercase);
62 
63  label prec = 0;
64  label offset = 7;
65  switch (writeFormat_)
66  {
67  case (wfShort):
68  case (wfFree):
69  {
70  prec = 8 - offset;
71  break;
72  }
73  case (wfLong):
74  {
75  prec = 16 - offset;
76  break;
77  }
78  default:
79  {
80  }
81  }
82 
83  os.precision(prec);
84 }
85 
86 
87 void Foam::nastranSurfaceWriter::writeCoord
88 (
89  const point& p,
90  const label pointi,
91  OFstream& os
92 ) const
93 {
94  // Fixed short/long formats:
95  // 1 GRID
96  // 2 ID : point ID - requires starting index of 1
97  // 3 CP : co-ordinate system ID (blank)
98  // 4 X1 : point x cp-ordinate
99  // 5 X2 : point x cp-ordinate
100  // 6 X3 : point x cp-ordinate
101  // 7 CD : co-ordinate system for displacements (blank)
102  // 8 PS : single point constraints (blank)
103  // 9 SEID : super-element ID
104 
105  switch (writeFormat_)
106  {
107  case wfShort:
108  {
109  os.setf(ios_base::left);
110  os << setw(8) << "GRID";
111  os.unsetf(ios_base::left);
112  os.setf(ios_base::right);
113  os << setw(8) << pointi + 1
114  << " "
115  << setw(8) << p.x()
116  << setw(8) << p.y()
117  << setw(8) << p.z()
118  << nl;
119  os.unsetf(ios_base::right);
120 
121  break;
122  }
123  case wfLong:
124  {
125  os.setf(ios_base::left);
126  os << setw(8) << "GRID*";
127  os.unsetf(ios_base::left);
128  os.setf(ios_base::right);
129  os << setw(16) << pointi + 1
130  << " "
131  << setw(16) << p.x()
132  << setw(16) << p.y()
133  << nl;
134  os.unsetf(ios_base::right);
135  os.setf(ios_base::left);
136  os << setw(8) << "*";
137  os.unsetf(ios_base::left);
138  os.setf(ios_base::right);
139  os << setw(16) << p.z()
140  << nl;
141  os.unsetf(ios_base::right);
142 
143  break;
144  }
145  case wfFree:
146  {
147  os << "GRID"
148  << ',' << pointi + 1
149  << ','
150  << ',' << p.x()
151  << ',' << p.y()
152  << ',' << p.z()
153  << nl;
154 
155  break;
156  }
157  default:
158  {
160  << "Unknown writeFormat enumeration" << abort(FatalError);
161  }
162  }
163 }
164 
165 void Foam::nastranSurfaceWriter::writeFace
166 (
167  const word& faceType,
168  const labelList& facePts,
169  label& nFace,
170  OFstream& os
171 ) const
172 {
173  // Only valid surface elements are CTRIA3 and CQUAD4
174 
175  // Fixed short/long formats:
176  // 1 CQUAD4
177  // 2 EID : element ID
178  // 3 PID : property element ID; default = EID (blank)
179  // 4 G1 : grid point index - requires starting index of 1
180  // 5 G2 : grid point index
181  // 6 G3 : grid point index
182  // 7 G4 : grid point index
183  // 8 onwards - not used
184 
185  // For CTRIA3 elements, cols 7 onwards are not used
186 
187  switch (writeFormat_)
188  {
189  case wfShort:
190  {
191  os.setf(ios_base::left);
192  os << setw(8) << faceType;
193  os.unsetf(ios_base::left);
194  os.setf(ios_base::right);
195  os << setw(8) << nFace++
196  << " ";
197 
198  forAll(facePts, i)
199  {
200  os << setw(8) << facePts[i] + 1;
201  }
202 
203  os << nl;
204  os.unsetf(ios_base::right);
205 
206  break;
207  }
208  case wfLong:
209  {
210  os.setf(ios_base::left);
211  os << setw(8) << word(faceType + "*");
212  os.unsetf(ios_base::left);
213  os.setf(ios_base::right);
214  os << setw(16) << nFace++
215  << " ";
216 
217  forAll(facePts, i)
218  {
219  os << setw(16) << facePts[i] + 1;
220  if (i == 1)
221  {
222  os << nl;
223  os.unsetf(ios_base::right);
224  os.setf(ios_base::left);
225  os << setw(8) << "*";
226  os.unsetf(ios_base::left);
227  os.setf(ios_base::right);
228  }
229  }
230 
231  os << nl;
232  os.unsetf(ios_base::right);
233 
234  break;
235  }
236  case wfFree:
237  {
238  os << faceType << ','
239  << ++nFace << ',';
240 
241  forAll(facePts, i)
242  {
243  os << ',' << facePts[i] + 1;
244  }
245 
246  os << nl;
247 
248  break;
249  }
250  default:
251  {
253  << "Unknown writeFormat enumeration" << abort(FatalError);
254  }
255  }
256 
257 }
258 
259 
260 void Foam::nastranSurfaceWriter::writeGeometry
261 (
262  const pointField& points,
263  const faceList& faces,
264  List<DynamicList<face>>& decomposedFaces,
265  OFstream& os
266 ) const
267 {
268  // write points
269 
270  os << "$" << nl
271  << "$ Points" << nl
272  << "$" << nl;
273 
274  forAll(points, pointi)
275  {
276  writeCoord(points[pointi], pointi, os);
277  }
278 
279 
280  // write faces
281 
282  os << "$" << nl
283  << "$ Faces" << nl
284  << "$" << nl;
285 
286  label nFace = 1;
287 
288  forAll(faces, facei)
289  {
290  const face& f = faces[facei];
291 
292  if (f.size() == 3)
293  {
294  writeFace("CTRIA3", faces[facei], nFace, os);
295  decomposedFaces[facei].append(faces[facei]);
296  }
297  else if (f.size() == 4)
298  {
299  writeFace("CQUAD4", faces[facei], nFace, os);
300  decomposedFaces[facei].append(faces[facei]);
301  }
302  else
303  {
304  // decompose poly face into tris
305  label nTri = 0;
306  faceList triFaces;
307  f.triangles(points, nTri, triFaces);
308 
309  forAll(triFaces, triI)
310  {
311  writeFace("CTRIA3", triFaces[triI], nFace, os);
312  decomposedFaces[facei].append(triFaces[triI]);
313  }
314  }
315  }
316 }
317 
318 
319 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
320 
322 :
323  surfaceWriter(),
324  writeFormat_(wfShort),
325  fieldMap_(),
326  scale_(1.0)
327 {}
328 
329 
331 :
332  surfaceWriter(),
333  writeFormat_(wfLong),
334  fieldMap_(),
335  scale_(options.lookupOrDefault("scale", 1.0))
336 {
337  if (options.found("format"))
338  {
339  writeFormat_ = writeFormatNames_.read(options.lookup("format"));
340  }
341 
342  List<Tuple2<word, word>> fieldSet(options.lookup("fields"));
343 
344  forAll(fieldSet, i)
345  {
346  fieldMap_.insert(fieldSet[i].first(), fieldSet[i].second());
347  }
348 }
349 
350 
351 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
352 
354 {}
355 
356 
357 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
358 
360 (
361  const fileName& outputDir,
362  const fileName& surfaceName,
363  const pointField& points,
364  const faceList& faces,
365  const bool verbose
366 ) const
367 {
368  if (!isDir(outputDir))
369  {
370  mkDir(outputDir);
371  }
372 
373  OFstream os(outputDir/surfaceName + ".dat");
374  formatOS(os);
375 
376  if (verbose)
377  {
378  Info<< "Writing nastran file to " << os.name() << endl;
379  }
380 
381  os << "TITLE=OpenFOAM " << surfaceName.c_str() << " mesh" << nl
382  << "$" << nl
383  << "BEGIN BULK" << nl;
384 
385  List<DynamicList<face>> decomposedFaces(faces.size());
386 
387  writeGeometry(points, faces, decomposedFaces, os);
388 
389  if (!isDir(outputDir))
390  {
391  mkDir(outputDir);
392  }
393 
394  os << "ENDDATA" << endl;
395 }
396 
397 
398 // ************************************************************************* //
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:431
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
A class for handling file names.
Definition: fileName.H:69
void unsetf(const ios_base::fmtflags uf)
Unset flags of stream.
Definition: IOstream.H:512
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
virtual int precision() const
Get precision of output field.
Definition: OSstream.C:293
ios_base::fmtflags setf(const ios_base::fmtflags f)
Set flags of stream.
Definition: IOstream.H:496
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
Output to file stream.
Definition: OFstream.H:82
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
nastranSurfaceWriter()
Construct null.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
const Cmpt & z() const
Definition: VectorI.H:87
virtual ~nastranSurfaceWriter()
Destructor.
const fileName & name() const
Return the name of the stream.
Definition: OFstream.H:120
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:51
label triangles(const pointField &points, label &triI, faceList &triFaces) const
Split into triangles using existing points.
Definition: face.C:837
const Cmpt & y() const
Definition: VectorI.H:81
virtual void write(const fileName &outputDir, const fileName &surfaceName, const pointField &points, const faceList &faces, const bool verbose=false) const
Write single surface geometry to file.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
bool isDir(const fileName &, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:528
A class for handling words, derived from string.
Definition: word.H:59
Convenience macros for instantiating writer methods for surfaceWriter classes.
defineSurfaceWriterWriteFields(nastranSurfaceWriter)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
const Cmpt & x() const
Definition: VectorI.H:75
Istream and Ostream manipulators taking arguments.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
static const char nl
Definition: Ostream.H:265
labelList f(nPoints)
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:289
makeSurfaceWriterType(ensightSurfaceWriter)
messageStream Info
Enum read(Istream &) const
Read a word from Istream and return the corresponding.
Definition: NamedEnum.C:61
static const NamedEnum< writeFormat, 3 > writeFormatNames_
Base class for surface writers.
Definition: surfaceWriter.H:54
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
IOstream & scientific(IOstream &io)
Definition: IOstream.H:582
Namespace for OpenFOAM.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:576