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-2019 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"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  makeSurfaceWriterType(nastranSurfaceWriter);
34  addToRunTimeSelectionTable(surfaceWriter, nastranSurfaceWriter, wordDict);
35 
36  // create write methods
37  defineSurfaceWriterWriteFields(nastranSurfaceWriter);
38 
39  template<>
41  {
42  "short",
43  "long",
44  "free"
45  };
46 
49 }
50 
51 
52 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
53 
54 void Foam::nastranSurfaceWriter::formatOS(OFstream& os) const
55 {
57 
58  // capitalize the E marker
59  os.setf(ios_base::uppercase);
60 
61  label prec = 0;
62  label offset = 7;
63  switch (writeFormat_)
64  {
65  case (wfShort):
66  case (wfFree):
67  {
68  prec = 8 - offset;
69  break;
70  }
71  case (wfLong):
72  {
73  prec = 16 - offset;
74  break;
75  }
76  default:
77  {
78  }
79  }
80 
81  os.precision(prec);
82 }
83 
84 
85 void Foam::nastranSurfaceWriter::writeCoord
86 (
87  const point& p,
88  const label pointi,
89  OFstream& os
90 ) const
91 {
92  // Fixed short/long formats:
93  // 1 GRID
94  // 2 ID : point ID - requires starting index of 1
95  // 3 CP : co-ordinate system ID (blank)
96  // 4 X1 : point x cp-ordinate
97  // 5 X2 : point x cp-ordinate
98  // 6 X3 : point x cp-ordinate
99  // 7 CD : co-ordinate system for displacements (blank)
100  // 8 PS : single point constraints (blank)
101  // 9 SEID : super-element ID
102 
103  switch (writeFormat_)
104  {
105  case wfShort:
106  {
107  os.setf(ios_base::left);
108  os << setw(8) << "GRID";
109  os.unsetf(ios_base::left);
110  os.setf(ios_base::right);
111  os << setw(8) << pointi + 1
112  << " "
113  << setw(8) << p.x()
114  << setw(8) << p.y()
115  << setw(8) << p.z()
116  << nl;
117  os.unsetf(ios_base::right);
118 
119  break;
120  }
121  case wfLong:
122  {
123  os.setf(ios_base::left);
124  os << setw(8) << "GRID*";
125  os.unsetf(ios_base::left);
126  os.setf(ios_base::right);
127  os << setw(16) << pointi + 1
128  << " "
129  << setw(16) << p.x()
130  << setw(16) << p.y()
131  << nl;
132  os.unsetf(ios_base::right);
133  os.setf(ios_base::left);
134  os << setw(8) << "*";
135  os.unsetf(ios_base::left);
136  os.setf(ios_base::right);
137  os << setw(16) << p.z()
138  << nl;
139  os.unsetf(ios_base::right);
140 
141  break;
142  }
143  case wfFree:
144  {
145  os << "GRID"
146  << ',' << pointi + 1
147  << ','
148  << ',' << p.x()
149  << ',' << p.y()
150  << ',' << p.z()
151  << nl;
152 
153  break;
154  }
155  default:
156  {
158  << "Unknown writeFormat enumeration" << abort(FatalError);
159  }
160  }
161 }
162 
163 void Foam::nastranSurfaceWriter::writeFace
164 (
165  const word& faceType,
166  const labelList& facePts,
167  label& nFace,
168  OFstream& os
169 ) const
170 {
171  // Only valid surface elements are CTRIA3 and CQUAD4
172 
173  // Fixed short/long formats:
174  // 1 CQUAD4
175  // 2 EID : element ID
176  // 3 PID : property element ID; default = EID (blank)
177  // 4 G1 : grid point index - requires starting index of 1
178  // 5 G2 : grid point index
179  // 6 G3 : grid point index
180  // 7 G4 : grid point index
181  // 8 onwards - not used
182 
183  // For CTRIA3 elements, cols 7 onwards are not used
184 
185  switch (writeFormat_)
186  {
187  case wfShort:
188  {
189  os.setf(ios_base::left);
190  os << setw(8) << faceType;
191  os.unsetf(ios_base::left);
192  os.setf(ios_base::right);
193  os << setw(8) << nFace++
194  << " ";
195 
196  forAll(facePts, i)
197  {
198  os << setw(8) << facePts[i] + 1;
199  }
200 
201  os << nl;
202  os.unsetf(ios_base::right);
203 
204  break;
205  }
206  case wfLong:
207  {
208  os.setf(ios_base::left);
209  os << setw(8) << word(faceType + "*");
210  os.unsetf(ios_base::left);
211  os.setf(ios_base::right);
212  os << setw(16) << nFace++
213  << " ";
214 
215  forAll(facePts, i)
216  {
217  os << setw(16) << facePts[i] + 1;
218  if (i == 1)
219  {
220  os << nl;
221  os.unsetf(ios_base::right);
222  os.setf(ios_base::left);
223  os << setw(8) << "*";
224  os.unsetf(ios_base::left);
225  os.setf(ios_base::right);
226  }
227  }
228 
229  os << nl;
230  os.unsetf(ios_base::right);
231 
232  break;
233  }
234  case wfFree:
235  {
236  os << faceType << ','
237  << ++nFace << ',';
238 
239  forAll(facePts, i)
240  {
241  os << ',' << facePts[i] + 1;
242  }
243 
244  os << nl;
245 
246  break;
247  }
248  default:
249  {
251  << "Unknown writeFormat enumeration" << abort(FatalError);
252  }
253  }
254 
255 }
256 
257 
258 void Foam::nastranSurfaceWriter::writeGeometry
259 (
260  const pointField& points,
261  const faceList& faces,
262  List<DynamicList<face>>& decomposedFaces,
263  OFstream& os
264 ) const
265 {
266  // write points
267 
268  os << "$" << nl
269  << "$ Points" << nl
270  << "$" << nl;
271 
272  forAll(points, pointi)
273  {
274  writeCoord(points[pointi], pointi, os);
275  }
276 
277 
278  // write faces
279 
280  os << "$" << nl
281  << "$ Faces" << nl
282  << "$" << nl;
283 
284  label nFace = 1;
285 
286  forAll(faces, facei)
287  {
288  const face& f = faces[facei];
289 
290  if (f.size() == 3)
291  {
292  writeFace("CTRIA3", faces[facei], nFace, os);
293  decomposedFaces[facei].append(faces[facei]);
294  }
295  else if (f.size() == 4)
296  {
297  writeFace("CQUAD4", faces[facei], nFace, os);
298  decomposedFaces[facei].append(faces[facei]);
299  }
300  else
301  {
302  // decompose poly face into tris
303  label nTri = 0;
304  faceList triFaces;
305  f.triangles(points, nTri, triFaces);
306 
307  forAll(triFaces, triI)
308  {
309  writeFace("CTRIA3", triFaces[triI], nFace, os);
310  decomposedFaces[facei].append(triFaces[triI]);
311  }
312  }
313  }
314 }
315 
316 
317 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
318 
320 :
321  surfaceWriter(),
322  writeFormat_(wfShort),
323  fieldMap_(),
324  scale_(1.0)
325 {}
326 
327 
329 :
330  surfaceWriter(),
331  writeFormat_(wfLong),
332  fieldMap_(),
333  scale_(options.lookupOrDefault("scale", 1.0))
334 {
335  if (options.found("format"))
336  {
337  writeFormat_ = writeFormatNames_.read(options.lookup("format"));
338  }
339 
340  List<Tuple2<word, word>> fieldSet(options.lookup("fields"));
341 
342  forAll(fieldSet, i)
343  {
344  fieldMap_.insert(fieldSet[i].first(), fieldSet[i].second());
345  }
346 }
347 
348 
349 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
350 
352 {}
353 
354 
355 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
356 
358 (
359  const fileName& outputDir,
360  const fileName& surfaceName,
361  const pointField& points,
362  const faceList& faces,
363  const bool verbose
364 ) const
365 {
366  if (!isDir(outputDir))
367  {
368  mkDir(outputDir);
369  }
370 
371  OFstream os(outputDir/surfaceName + ".dat");
372  formatOS(os);
373 
374  if (verbose)
375  {
376  Info<< "Writing nastran file to " << os.name() << endl;
377  }
378 
379  os << "TITLE=OpenFOAM " << surfaceName.c_str() << " mesh" << nl
380  << "$" << nl
381  << "BEGIN BULK" << nl;
382 
383  List<DynamicList<face>> decomposedFaces(faces.size());
384 
385  writeGeometry(points, faces, decomposedFaces, os);
386 
387  if (!isDir(outputDir))
388  {
389  mkDir(outputDir);
390  }
391 
392  os << "ENDDATA" << endl;
393 }
394 
395 
396 // ************************************************************************* //
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:438
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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:79
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:158
#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:539
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
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:290
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:583