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-------------------------------------------------------------------------------
11License
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
35Foam::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
53void 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
159void 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
306void 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
420(
421 const polyMesh& mesh,
422 const scalar scaleFactor,
423 const bool writeBndFile
424)
425:
426 meshWriter(mesh, scaleFactor),
427 writeBoundary_(writeBndFile)
428{
431 getCellTable();
432}
433
434
435// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
436
438{
439 fileName baseName(meshName);
440
441 if (baseName.empty())
442 {
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 {
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// ************************************************************************* //
Output to file stream, using an OSstream.
Definition: OFstream.H:57
void readDict(const objectRegistry &, const word &name="boundaryRegion", const fileName &instance="constant")
Read constant/boundaryRegion.
@ PRISM
prism
Definition: cellModel.H:83
void readDict(const objectRegistry &, const word &name="cellTable", const fileName &instance="constant")
Read constant/cellTable.
Definition: cellTable.C:312
reference ref() const
A reference to the entry (Error if not found)
Definition: dictionary.H:225
void removeFiles() const
Remove all files from mesh instance()
Definition: faMesh.C:718
static const Map< FixedList< int, 6 > > foamToStarFaceAddr
Face addressing from OpenFOAM faces to PROSTAR faces.
Definition: STARCDCore.H:133
static const char *const defaultBoundaryName
The name for default (unassigned) boundaries.
Definition: STARCDCore.H:108
Writes polyMesh in PROSTAR (v4) bnd/cel/vrt format.
A class for handling file names.
Definition: fileName.H:76
virtual bool write()
Write the output fields.
Write OpenFOAM meshes and/or results to another CFD format.
Definition: meshWriter.H:83
boundaryRegion boundaryRegion_
boundaryRegion persistent data saved as a dictionary
Definition: meshWriter.H:104
cellTable cellTable_
cellTable persistent data saved as a dictionary
Definition: meshWriter.H:107
static string defaultMeshName
Specify a default mesh name.
Definition: meshWriter.H:117
const polyMesh & mesh_
Mesh reference.
Definition: meshWriter.H:98
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:456
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:324
const polyBoundaryMesh & patches
dynamicFvMesh & mesh
OBJstream os(runTime.globalPath()/outputName)
const cellShapeList & cells
label cellId
#define WarningInFunction
Report a warning using Foam::Warning.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:78
List< cellShape > cellShapeList
List of cellShapes and PtrList of List of cellShape.
Definition: cellShapeList.H:45
List< label > labelList
A List of labels.
Definition: List.H:66
List< cell > cellList
A List of cells.
Definition: cellListFwd.H:47
static void writeHeader(Ostream &os, const word &fieldName)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
labelList f(nPoints)
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333