STARCDMeshWriter.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "STARCDMeshWriter.H"
30 #include "Time.H"
31 #include "OFstream.H"
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 Foam::label Foam::fileFormats::STARCDMeshWriter::findDefaultBoundary() const
36 {
37  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
38 
39  // Find "Default_Boundary_Region" if it exists
40  forAll(patches, patchi)
41  {
42  if (defaultBoundaryName == patches[patchi].name())
43  {
44  return patchi;
45  break;
46  }
47  }
48 
49  return -1;
50 }
51 
52 
53 void Foam::fileFormats::STARCDMeshWriter::getCellTable()
54 {
55  // Read constant/polyMesh/propertyName
56  IOList<label> ioList
57  (
58  IOobject
59  (
60  "cellTableId",
61  mesh_.time().constant(),
63  mesh_,
66  false
67  )
68  );
69 
70  bool useCellZones = false;
71  cellTableId_.setSize(mesh_.nCells(), -1);
72 
73  // get information from constant/polyMesh/cellTableId if possible
74  if (ioList.headerOk())
75  {
76  if (ioList.size() == mesh_.nCells())
77  {
78  cellTableId_.transfer(ioList);
79 
80  if (cellTable_.empty())
81  {
82  Info<< "no cellTable information available" << endl;
83  }
84  }
85  else
86  {
88  << ioList.objectPath() << " has incorrect number of cells "
89  << " - use cellZone information"
90  << endl;
91 
92  ioList.clear();
93  useCellZones = true;
94  }
95  }
96  else
97  {
98  useCellZones = true;
99  }
100 
101 
102  if (useCellZones)
103  {
104  if (cellTable_.empty())
105  {
106  Info<< "created cellTable from cellZones" << endl;
107  cellTable_ = mesh_;
108  }
109 
110  // track if there are unzoned cells
111  label nUnzoned = mesh_.nCells();
112 
113  // get the cellZone <-> cellTable correspondence
114  Info<< "matching cellZones to cellTable" << endl;
115 
116  for (const cellZone& cZone : mesh_.cellZones())
117  {
118  if (cZone.size())
119  {
120  nUnzoned -= cZone.size();
121 
122  label tableId = cellTable_.findIndex(cZone.name());
123  if (tableId < 0)
124  {
125  dictionary dict;
126 
127  dict.add("Label", cZone.name());
128  dict.add("MaterialType", "fluid");
129  tableId = cellTable_.append(dict);
130  }
131 
132  for (const label celli : cZone)
133  {
134  cellTableId_[celli] = tableId;
135  }
136  }
137  }
138 
139  if (nUnzoned)
140  {
141  dictionary dict;
142 
143  dict.add("Label", "__unZonedCells__");
144  dict.add("MaterialType", "fluid");
145  const label tableId = cellTable_.append(dict);
146 
147  forAll(cellTableId_, i)
148  {
149  if (cellTableId_[i] < 0)
150  {
151  cellTableId_[i] = tableId;
152  }
153  }
154  }
155  }
156 }
157 
158 
159 void Foam::fileFormats::STARCDMeshWriter::writeCells
160 (
161  const fileName& prefix
162 ) const
163 {
164  OFstream os(starFileName(prefix, STARCDCore::CEL_FILE));
166 
167  //
168  // Mapping between OpenFOAM and PROSTAR primitives
169  //
170  const Map<label> shapeLookupIndex
171  {
176  };
177 
178  const cellShapeList& shapes = mesh_.cellShapes();
179  const cellList& cells = mesh_.cells();
180  const faceList& faces = mesh_.faces();
181  const labelList& owner = mesh_.faceOwner();
182 
183  Info<< "Writing " << os.name() << " : "
184  << cells.size() << " cells" << endl;
185 
187  {
188  const label tableId = cellTableId_[cellId];
189  label materialType = STARCDCore::starcdFluidType; // 1(fluid)
190  if (cellTable_.found(tableId))
191  {
192  const dictionary& dict = cellTable_[tableId];
193  word matType;
194 
195  if
196  (
197  dict.readIfPresent("MaterialType", matType)
198  && matType == "solid"
199  )
200  {
201  materialType = STARCDCore::starcdSolidType; // 2(solid)
202  }
203  }
204 
205  const cellShape& shape = shapes[cellId];
206  const label mapIndex = shape.model().index();
207 
208  // A registered primitive type
209  if (shapeLookupIndex.found(mapIndex))
210  {
211  const label shapeId = shapeLookupIndex[mapIndex];
212  const labelList& vrtList = shapes[cellId];
213 
214  os << cellId + 1
215  << ' ' << shapeId
216  << ' ' << vrtList.size()
217  << ' ' << tableId
218  << ' ' << materialType;
219 
220  // Primitives have <= 8 vertices, but prevent overrun anyhow
221  // indent following lines for ease of reading
222  label count = 0;
223  for (const label pointi : vrtList)
224  {
225  if ((count % 8) == 0)
226  {
227  os << nl
228  << " " << cellId + 1;
229  }
230  os << ' ' << pointi + 1;
231  ++count;
232  }
233  os << nl;
234  }
235  else
236  {
237  // Treat as general polyhedral
238  const label shapeId = STARCDCore::starcdPoly;
239  const labelList& cFaces = cells[cellId];
240 
241  // create (beg,end) indices
242  List<label> indices(cFaces.size() + 1);
243  indices[0] = indices.size();
244 
245  label count = indices.size();
246  // determine the total number of vertices
247  forAll(cFaces, facei)
248  {
249  count += faces[cFaces[facei]].size();
250  indices[facei+1] = count;
251  }
252 
253  os << cellId + 1
254  << ' ' << shapeId
255  << ' ' << count
256  << ' ' << tableId
257  << ' ' << materialType;
258 
259  // Write indices - max 8 per line
260  // indent following lines for ease of reading
261  count = 0;
262  for (const label pointi : indices)
263  {
264  if ((count % 8) == 0)
265  {
266  os << nl
267  << " " << cellId + 1;
268  }
269  os << ' ' << pointi;
270  ++count;
271  }
272 
273  // write faces - max 8 per line
274  for (const label meshFace : cFaces)
275  {
276  face f;
277 
278  if (owner[meshFace] == cellId)
279  {
280  f = faces[meshFace];
281  }
282  else
283  {
284  f = faces[meshFace].reverseFace();
285  }
286 
287  for (const label pointi : f)
288  {
289  if ((count % 8) == 0)
290  {
291  os << nl
292  << " " << cellId + 1;
293  }
294 
295  os << ' ' << pointi + 1;
296  ++count;
297  }
298  }
299 
300  os << endl;
301  }
302  }
303 }
304 
305 
306 void Foam::fileFormats::STARCDMeshWriter::writeBoundary
307 (
308  const fileName& prefix
309 ) const
310 {
311  OFstream os(starFileName(prefix, STARCDCore::BND_FILE));
313 
314  const cellShapeList& shapes = mesh_.cellShapes();
315  const cellList& cells = mesh_.cells();
316  const faceList& faces = mesh_.faces();
317  const labelList& owner = mesh_.faceOwner();
318  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
319 
320  //
321  // Mapping between OpenFOAM and PROSTAR primitives
322  // - needed for face mapping
323  //
324  const Map<label> shapeLookupIndex =
325  {
330  };
331 
332  Info<< "Writing " << os.name() << " : "
333  << (mesh_.nFaces() - patches[0].start()) << " boundaries" << endl;
334 
335 
336  const label defaultId = findDefaultBoundary();
337 
338  //
339  // write boundary faces - skip Default_Boundary_Region entirely
340  //
341  label boundId = 0;
342  forAll(patches, patchi)
343  {
344  label regionId = patchi;
345  if (regionId == defaultId)
346  {
347  continue; // skip - already written
348  }
349  else if (defaultId == -1 || regionId < defaultId)
350  {
351  ++regionId;
352  }
353 
354  label patchStart = patches[patchi].start();
355  label patchSize = patches[patchi].size();
356  word bndType = boundaryRegion_.boundaryType(patches[patchi].name());
357 
358  for
359  (
360  label facei = patchStart;
361  facei < (patchStart + patchSize);
362  ++facei
363  )
364  {
365  label cellId = owner[facei];
366  const labelList& cFaces = cells[cellId];
367  const cellShape& shape = shapes[cellId];
368  label cellFaceId = cFaces.find(facei);
369 
370  // Info<< "cell " << cellId + 1 << " face " << facei
371  // << " == " << faces[facei]
372  // << " is index " << cellFaceId << " from " << cFaces;
373 
374  // Unfortunately, the order of faces returned by
375  // primitiveMesh::cells() is not necessarily the same
376  // as defined by primitiveMesh::cellShapes()
377  // Thus, for registered primitive types, do the lookup ourselves.
378  // Finally, the cellModel face number is re-mapped to the
379  // STARCD local face number
380 
381  label mapIndex = shape.model().index();
382 
383  // A registered primitive type
384  if (shapeLookupIndex.found(mapIndex))
385  {
386  const faceList sFaces = shape.faces();
387  forAll(sFaces, sFacei)
388  {
389  if (faces[facei] == sFaces[sFacei])
390  {
391  cellFaceId = sFacei;
392  break;
393  }
394  }
395 
396  mapIndex = shapeLookupIndex[mapIndex];
397  cellFaceId =
398  STARCDCore::foamToStarFaceAddr[mapIndex][cellFaceId];
399  }
400  // Info<< endl;
401 
402  ++boundId;
403 
404  os
405  << boundId
406  << ' ' << cellId + 1
407  << ' ' << cellFaceId + 1
408  << ' ' << regionId
409  << ' ' << 0
410  << ' ' << bndType.c_str()
411  << endl;
412  }
413  }
414 }
415 
416 
417 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
418 
419 Foam::fileFormats::STARCDMeshWriter::STARCDMeshWriter
420 (
421  const polyMesh& mesh,
422  const scalar scaleFactor,
423  const bool writeBndFile
424 )
425 :
426  meshWriter(mesh, scaleFactor),
427  writeBoundary_(writeBndFile)
428 {
429  boundaryRegion_.readDict(mesh_);
430  cellTable_.readDict(mesh_);
431  getCellTable();
432 }
433 
434 
435 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
436 
438 {
439  fileName baseName(meshName);
440 
441  if (baseName.empty())
442  {
443  baseName = meshWriter::defaultMeshName;
444 
445  if
446  (
447  mesh_.time().timeName() != "0"
448  && mesh_.time().timeName() != mesh_.time().constant()
449  )
450  {
451  baseName += "_" + mesh_.time().timeName();
452  }
453  }
454 
455  STARCDCore::removeFiles(baseName);
456 
457  // Points
458  {
459  OFstream os
460  (
461  starFileName(baseName, STARCDCore::VRT_FILE)
462  );
463 
464  Info<< "Writing " << os.name() << " : "
465  << mesh_.nPoints() << " points" << endl;
466 
467  writePoints(os, mesh_.points(), scaleFactor_);
468  }
469 
470  // Cells
471  writeCells(baseName);
472 
473  // Boundaries
474  if (writeBoundary_)
475  {
476  writeBoundary(baseName);
477  }
478 
479  return true;
480 }
481 
482 
483 // ************************************************************************* //
Foam::fileFormats::STARCDCore::starcdPyr
Definition: STARCDCore.H:102
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
Foam::cellModel::index
label index() const noexcept
Return index of model in the model list.
Definition: cellModelI.H:37
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::fileFormats::STARCDMeshWriter::write
virtual bool write(const fileName &meshName=fileName::null) const
Write volume mesh.
Definition: STARCDMeshWriter.C:437
Foam::cellModel::HEX
hex
Definition: cellModel.H:81
Foam::polyMesh::meshSubDir
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:321
Foam::cellShapeList
List< cellShape > cellShapeList
List of cellShapes and PtrList of List of cellShape.
Definition: cellShapeList.H:45
Foam::fileFormats::STARCDCore::foamToStarFaceAddr
static const Map< FixedList< int, 6 > > foamToStarFaceAddr
Face addressing from OpenFOAM faces to PROSTAR faces.
Definition: STARCDCore.H:133
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::writeHeader
static void writeHeader(Ostream &os, const word &fieldName)
Definition: rawSurfaceWriterImpl.C:66
Foam::cellModel::TET
tet
Definition: cellModel.H:85
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fileFormats::STARCDCore::VRT_FILE
Definition: STARCDCore.H:77
OFstream.H
Foam::fileFormats::STARCDCore::starcdSolidType
Definition: STARCDCore.H:86
Foam::fileFormats::STARCDCore::defaultBoundaryName
static const char *const defaultBoundaryName
The name for default (unassigned) boundaries.
Definition: STARCDCore.H:108
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::fileFormats::STARCDCore::starcdPoly
Definition: STARCDCore.H:103
Foam::IOobject::READ_IF_PRESENT
Definition: IOobject.H:187
Foam::cellList
List< cell > cellList
A List of cells.
Definition: cellListFwd.H:47
Foam::cellModel::PRISM
prism
Definition: cellModel.H:83
Foam::cellModel::ref
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
Definition: cellModels.C:157
Foam::fileFormats::STARCDCore::starcdPrism
Definition: STARCDCore.H:100
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::fileFormats::STARCDCore::CEL_FILE
Definition: STARCDCore.H:76
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fileFormats::STARCDCore::starcdFluidType
Definition: STARCDCore.H:85
Foam::meshWriter::mesh_
const polyMesh & mesh_
Mesh reference.
Definition: meshWriter.H:98
Foam::fileFormats::STARCDCore::BND_FILE
Definition: STARCDCore.H:78
cellId
label cellId
Definition: interrogateWallPatches.H:67
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Time.H
Foam::meshWriter::defaultMeshName
static string defaultMeshName
Specify a default mesh name.
Definition: meshWriter.H:117
Foam::cellModel::PYR
pyr
Definition: cellModel.H:84
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::fileFormats::STARCDCore::HEADER_CEL
Definition: STARCDCore.H:68
Foam::fileFormats::STARCDCore::starcdTet
Definition: STARCDCore.H:101
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
STARCDMeshWriter.H
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
Foam::fileFormats::STARCDCore::removeFiles
static void removeFiles(const fileName &baseName)
Remove existing PROSTAR files for the given base file-name.
Definition: STARCDCore.C:186
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::meshWriter
Write OpenFOAM meshes and/or results to another CFD format.
Definition: meshWriter.H:82
Foam::fileFormats::STARCDCore::starcdHex
Definition: STARCDCore.H:99
Foam::fileFormats::STARCDCore::HEADER_BND
Definition: STARCDCore.H:70