1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 Converts a GAMBIT mesh to FOAM format.
31 \*---------------------------------------------------------------------------*/
37 /* ------------------------------------------------------------------------- *\
38 ------ local definitions
39 \* ------------------------------------------------------------------------- */
41 #include "scalarList.H"
42 #include "IStringStream.H"
49 #include "emptyPolyPatch.H"
50 #include "preservePatchTypes.H"
51 #include "cellModeller.H"
52 #include "cellShape.H"
54 #include "SLPtrList.H"
58 label nCellStreams = 0;
61 label nCoordDirections = 0;
62 label nVectorComponents = 0;
66 labelList pointMap(0);
68 PtrList<labelList> cellLabels(0);
70 labelList cellTypes(0);
71 labelList cellStreamIDs(0);
73 wordList patchNames(0);
74 labelListList patchCells(0);
75 labelListList patchCellFaces(0);
76 label nValuesForPatchFaces = 0;
78 // Dummy yywrap to keep yylex happy at compile time.
79 // It is called by yylex but is not used as the mechanism to change file.
81 #if YY_FLEX_SUBMINOR_VERSION < 34
82 extern "C" int yywrap()
84 int yyFlexLexer::yywrap()
94 some_space {one_space}+
100 dec_digit [[:digit:]]
102 hex_digit [[:xdigit:]]
110 identifier {alpha}({alpha}|{digit})*
112 label [0-9]{dec_digit}*
115 word ({alpha}|{digit}|{dotColonDash})*
117 exponent_part [eE][-+]?{digit}+
118 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
120 double ((({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))|0)
126 labelListElement {space}{zeroLabel}
127 scalarListElement {space}{double}
128 labelList ({labelListElement}+{space})
129 scalarList ({scalarListElement}+{space})
132 text ({space}({word}*{space})*\n)
134 dateDDMMYYYY ({digit}{digit}"/"{digit}{digit}"/"{digit}{digit}{digit}{digit})
135 dateDDMonYYYY ((({digit}{digit}{space})|({digit}{space})){alpha}*{space}{digit}{digit}{digit}{digit})
136 time ({digit}{digit}":"{digit}{digit}":"{digit}{digit})
138 versionNumber ({digit}|".")*
140 controlInfo ^{space}"CONTROL INFO"{space}{versionNumber}
141 applicationData ^{space}"APPLICATION DATA"{space}{versionNumber}
142 nodalCoords ^{space}"NODAL COORDINATES"{space}{versionNumber}
143 cellsAndElements ^{space}"ELEMENTS/CELLS"{space}{versionNumber}
144 cellStreams ^{space}"ELEMENT GROUP"{space}{versionNumber}
145 boundaryPatch ^{space}"BOUNDARY CONDITIONS"{space}{versionNumber}
146 faceConnectivity ^{space}"FACE CONNECTIVITY"{space}{versionNumber}
148 endOfSection ^{space}"ENDOFSECTION"{space}
150 program {space}"PROGRAM:"{space}
151 version {space}"VERSION:"{space}
153 group {space}"GROUP:"{space}
154 elements {space}"ELEMENTS:"{space}
155 material {space}"MATERIAL:"{space}
156 nFlags {space}"NFLAGS:"{space}
157 mtype {space}"MTYPE:"{space}
160 /* ------------------------------------------------------------------------- *\
161 ----- Exclusive start states -----
162 \* ------------------------------------------------------------------------- */
178 %x readCellStreamGroupID
179 %x readCellStreamNElements
180 %x readCellStreamMaterial
181 %x readCellStreamNFlags
183 %x boundaryPatchParams
184 %x boundaryPatchFaces
193 label nCellContinuationLines = 0;
194 label curNumberOfNodes = 0;
195 label curNumberOfCells = 0;
196 label curGroupID = 0;
197 label nFlagsForStream = 0;
198 label curBoundaryPatch = 0;
199 label curPatchFace = 0;
203 /* ------------------------------------------------------------------------- *\
204 ------ Start Lexing ------
205 \* ------------------------------------------------------------------------- */
207 /* ------ Reading control header ------ */
210 BEGIN(readControlHeader);
214 <readControlHeader>{starStar}{space}{text} {
221 Info << "Title: " << YYText();
226 <controlInfo>{spaceNl}{program} {
227 BEGIN(readProgramID);
231 <readProgramID>{space}{word} {
233 Info << "Written by " << YYText() << " ";
238 <controlInfo>{spaceNl}{version} {
239 BEGIN(readVersionID);
243 <readVersionID>{space}{versionNumber} {
245 Info << " version " << YYText() << endl;
250 <controlInfo>{space}{dateDDMonYYYY}{space}{time} {
252 Info << "File written on " << YYText() << endl;
256 <controlInfo>{space}{dateDDMMYYYY}{space}{time} {
258 Info << "File written on " << YYText() << endl;
262 <controlInfo>{spaceNl}"NUMNP"{space}"NELEM"{space}"NGRPS"{space}"NBSETS"{space}("NDFCD"|"NDCFD"){space}"NDFVL"{space}\n {
263 BEGIN(globalMeshData);
267 <globalMeshData>{spaceNl}{label}{space}{label}{space}{label}{space}{label}{space}{label}{space}{label}{space}\n {
269 IStringStream nodeStream(YYText());
271 nPoints = readLabel(nodeStream);
272 nCells = readLabel(nodeStream);
273 nCellStreams = readLabel(nodeStream);
274 nPatches = readLabel(nodeStream);
275 nCoordDirections = readLabel(nodeStream);
276 nVectorComponents = readLabel(nodeStream);
278 // reset list sizes - now known!
279 points.setSize(nPoints);
280 pointMap.setSize(nPoints);
282 cellLabels.setSize(nCells);
283 cellMap.setSize(nCells);
284 cellTypes.setSize(nCells);
285 cellStreamIDs.setSize(nCells);
287 patchNames.setSize(nPatches);
288 patchCells.setSize(nPatches);
289 patchCellFaces.setSize(nPatches);
291 Info<< " number of points: " << nPoints << endl
292 << " number of cells: " << nCells << endl
293 << " number of patches: " << nPatches << endl;
299 /* ------ Reading nodal coordinates ------ */
301 {nodalCoords}{spaceNl} {
303 curNumberOfNodes = 0;
304 Info << "Reading nodal coordinates" << endl;
309 <nodalCoords>{spaceNl}{label}{space}{x}{space}{y}{space}{z}{space}\n {
311 IStringStream nodeStream(YYText());
313 label nodeI(readLabel(nodeStream));
315 // Note: coordinates must be read one at the time.
316 scalar x = readScalar(nodeStream);
317 scalar y = readScalar(nodeStream);
318 scalar z = readScalar(nodeStream);
320 // add mapping and scalced node to the list
321 pointMap[curNumberOfNodes] = nodeI;
322 points[curNumberOfNodes] = point(x, y, z);
327 /* ------ Reading cells and elements ------ */
329 {cellsAndElements}{spaceNl} {
331 curNumberOfCells = 0;
332 Info << "Reading cells" << endl;
333 BEGIN(cellsAndElements);
336 <cellsAndElements>{spaceNl}{label}{space}{label}{space}{label}{labelList} {
338 IStringStream elementStream(YYText());
340 label cellI(readLabel(elementStream));
341 label cellType(readLabel(elementStream));
342 label nVertices(readLabel(elementStream));
344 // reset number of continuation lines
345 nCellContinuationLines = 0;
347 cellMap[curNumberOfCells] = cellI;
348 cellTypes[curNumberOfCells] = cellType;
349 cellLabels.set(curNumberOfCells, new labelList(nVertices));
351 labelList& curLabels = cellLabels[curNumberOfCells];
353 // Find out how many labels are expected. If less or equal to
354 // seven, read them all and finish with it. If there is more,
355 // set read of the next line
356 label labelsToRead = min(8, nVertices);
358 for (; labelI < labelsToRead; labelI++)
360 if (elementStream.eof()) break;
362 // Check token to avoid trailing space.
363 token curLabelTok(elementStream);
364 if (curLabelTok.isLabel())
366 curLabels[labelI] = curLabelTok.labelToken();
374 if (labelI < nVertices)
385 <cellContLine>{spaceNl}{labelList} {
387 IStringStream elementStream(YYText());
389 nCellContinuationLines++;
391 labelList& curLabels = cellLabels[curNumberOfCells];
393 label labelsToRead = min
395 (nCellContinuationLines + 1)*7,
401 label labelI = nCellContinuationLines*7;
402 labelI < labelsToRead;
406 curLabels[labelI] = readLabel(elementStream);
409 // if read is finished, go back to reading cells
410 if (curLabels.size() < (nCellContinuationLines + 1)*7)
414 BEGIN(cellsAndElements);
419 /* ------ Reading element group information ------ */
421 {cellStreams}{spaceNl} {
422 Info << "Reading cell streams" << endl;
427 <cellStreams>{spaceNl}{group} {
428 BEGIN(readCellStreamGroupID);
432 <readCellStreamGroupID>{space}{label} {
433 IStringStream groupStream(YYText());
437 FatalErrorIn("gambitToFoam::main")
438 << "<readCellStreamGroupID>{space}{label} : "
439 << "trying to reset group ID while active"
440 << abort(FatalError);
444 curGroupID = readLabel(groupStream);;
451 <cellStreams>{spaceNl}{elements} {
452 BEGIN(readCellStreamNElements);
456 <readCellStreamNElements>{space}{label} {
458 IStringStream nElementsStream(YYText());
460 readLabel(nElementsStream);
465 <cellStreams>{spaceNl}{material} {
466 BEGIN(readCellStreamMaterial);
470 <readCellStreamMaterial>{space}{label} {
472 IStringStream materialIDstream(YYText());
474 readLabel(materialIDstream);
480 <cellStreams>{spaceNl}{nFlags} {
481 BEGIN(readCellStreamNFlags);
485 <readCellStreamNFlags>{space}{label} {
487 IStringStream nFlagsStream(YYText());
489 nFlagsForStream = readLabel(nFlagsStream);
491 BEGIN(cellStreamTitle);
495 <cellStreamTitle>{spaceNl}{word}{spaceNl} {
497 word streamName(Foam::string::validate<word>(YYText()));
499 BEGIN(cellStreamFlags);
503 <cellStreamFlags>{labelList} {
504 Info << "Reading cell stream labels" << endl;
505 BEGIN(cellStreamLabels);
509 <cellStreamLabels>{spaceNl}{labelList} {
511 IStringStream nFlagsStream(YYText());
514 while (nFlagsStream.read(cellLabel))
516 cellStreamIDs[cellLabel - 1] = curGroupID;
519 // reset current group ID and a number of flags
525 /* ------ Reading end of section and others ------ */
527 <cellStreamLabels>{endOfSection}\n {
529 Info << "Finished reading cell stream labels" << endl;
531 // reset current group ID and a number of flags
539 {boundaryPatch}{spaceNl} {
541 Info << "Reading patches" << endl;
542 BEGIN(boundaryPatchParams);
546 <boundaryPatchParams>{spaceNl}{word}{labelList} {
548 IStringStream patchParamsStream(YYText());
550 patchParamsStream.read(patchNames[curBoundaryPatch]);
552 readLabel(patchParamsStream);
553 label nEntry(readLabel(patchParamsStream));
554 nValuesForPatchFaces = readLabel(patchParamsStream);
556 patchCells[curBoundaryPatch].setSize(nEntry);
557 patchCellFaces[curBoundaryPatch].setSize(nEntry);
559 Info<< "patch " << curBoundaryPatch
560 << ": name: " << patchNames[curBoundaryPatch]
563 BEGIN(boundaryPatchFaces);
567 <boundaryPatchFaces>{spaceNl}{label}{space}{label}{space}{label}({scalarList}|{space}\n) {
569 // Face-based boundary condition
570 IStringStream patchFacesStream(YYText());
572 patchCells[curBoundaryPatch][curPatchFace] =
573 readLabel(patchFacesStream);
574 readLabel(patchFacesStream);
575 patchCellFaces[curBoundaryPatch][curPatchFace] =
576 readLabel(patchFacesStream);
578 // patch face values currently discarded
579 if (nValuesForPatchFaces > 0)
581 scalarList patchFaceValues(nValuesForPatchFaces);
583 forAll (patchFaceValues, fI)
585 patchFaceValues[fI] = readScalar(patchFacesStream);
593 <boundaryPatchFaces>{spaceNl}{label}({scalarList}|\n) {
595 // Vertex-based boundary condition
596 FatalErrorIn("gambitToFoam::main")
597 << "<boundaryPatchFaces>{spaceNl}{label}{scalarList} : "
598 << "boundary condition specified on vertices not supported"
599 << abort(FatalError);
603 <boundaryPatchFaces>{endOfSection}\n {
611 /* ------ Reading end of section and others ------ */
613 <controlInfo,nodalCoords,cellsAndElements>{endOfSection}\n {
618 /* ------ Ignore remaining space and \n s. Any other characters are errors. */
623 /* ------ On EOF return to previous file, if none exists terminate. ------ */
631 #include "fileName.H"
635 int main(int argc, char *argv[])
637 argList::noParallel();
638 argList::validArgs.append("GAMBIT file");
639 argList::validOptions.insert("scale", "scale factor");
641 argList args(argc, argv);
648 scalar scaleFactor = 1.0;
649 if (args.options().found("scale"))
651 scaleFactor = atof(args.options()["scale"].c_str());
654 # include "createTime.H"
656 fileName gambitFile(args.additionalArgs()[0]);
657 ifstream gambitStream(gambitFile.c_str());
661 FatalErrorIn("gambitToFoam::main")
663 << ": file " << gambitFile << " not found"
664 << abort(FatalError);
667 yyFlexLexer lexer(&gambitStream);
668 while(lexer.yylex() != 0)
671 Info << "Finished lexing" << endl;
673 // make a point mapping array
674 label maxPointIndex = 0;
676 forAll (pointMap, pointI)
678 if (pointMap[pointI] > maxPointIndex)
680 maxPointIndex = pointMap[pointI];
685 labelList pointLookup(maxPointIndex + 1, -1);
687 forAll (pointMap, pointI)
689 pointLookup[pointMap[pointI] ] = pointI;
692 // make a cell mapping array
693 label maxCellIndex = 0;
695 forAll (cellMap, cellI)
697 if (cellMap[cellI] > maxCellIndex)
699 maxCellIndex = cellMap[cellI];
703 labelList cellLookup(maxCellIndex + 1);
705 forAll (cellMap, cellI)
707 cellLookup[cellMap[cellI] ] = cellI;
710 const cellModel& hex = *(cellModeller::lookup("hex"));
711 const cellModel& prism = *(cellModeller::lookup("prism"));
712 const cellModel& pyr = *(cellModeller::lookup("pyr"));
713 const cellModel& tet = *(cellModeller::lookup("tet"));
715 labelList labelsHex(8);
716 labelList labelsPrism(6);
717 labelList labelsPyramid(5);
718 labelList labelsTet(4);
720 cellShapeList cells(cellLabels.size());
722 forAll (cellTypes, cellI)
724 const labelList& curCellLabels = cellLabels[cellI];
727 if (cellTypes[cellI] == 6)
729 labelsTet[0] = pointLookup[curCellLabels[0] ];
730 labelsTet[1] = pointLookup[curCellLabels[2] ];
731 labelsTet[2] = pointLookup[curCellLabels[3] ];
732 labelsTet[3] = pointLookup[curCellLabels[1] ];
734 cells[cellI] = cellShape(tet, labelsTet);
737 // Square-based pyramid
738 else if (cellTypes[cellI] == 7)
740 labelsPyramid[0] = pointLookup[curCellLabels[0] ];
741 labelsPyramid[1] = pointLookup[curCellLabels[1] ];
742 labelsPyramid[2] = pointLookup[curCellLabels[3] ];
743 labelsPyramid[3] = pointLookup[curCellLabels[2] ];
744 labelsPyramid[4] = pointLookup[curCellLabels[4] ];
746 cells[cellI] = cellShape(pyr, labelsPyramid);
750 else if (cellTypes[cellI] == 5)
752 labelsPrism[0] = pointLookup[curCellLabels[0] ];
753 labelsPrism[1] = pointLookup[curCellLabels[1] ];
754 labelsPrism[2] = pointLookup[curCellLabels[2] ];
755 labelsPrism[3] = pointLookup[curCellLabels[3] ];
756 labelsPrism[4] = pointLookup[curCellLabels[4] ];
757 labelsPrism[5] = pointLookup[curCellLabels[5] ];
759 cells[cellI] = cellShape(prism, labelsPrism);
763 else if (cellTypes[cellI] == 4)
765 labelsHex[0] = pointLookup[curCellLabels[0] ];
766 labelsHex[1] = pointLookup[curCellLabels[1] ];
767 labelsHex[2] = pointLookup[curCellLabels[3] ];
768 labelsHex[3] = pointLookup[curCellLabels[2] ];
769 labelsHex[4] = pointLookup[curCellLabels[4] ];
770 labelsHex[5] = pointLookup[curCellLabels[5] ];
771 labelsHex[6] = pointLookup[curCellLabels[7] ];
772 labelsHex[7] = pointLookup[curCellLabels[6] ];
774 cells[cellI] = cellShape(hex, labelsHex);
778 // give foam model face number given a fluent model face number
779 label faceIndex[8][6] =
781 {-1, -1, -1, -1, -1, -1}, // 0
782 {-1, -1, -1, -1, -1, -1}, // 1
783 {-1, -1, -1, -1, -1, -1}, // 2
784 { 2, 1, 3, 0, 4, 5}, // Hex (3)
785 {-1, -1, -1, -1, -1, -1}, // 4
786 { 4, 3, 2, 0, 1, -1}, // Triangular prism (5)
787 { 0, 4, 3, 2, 1, -1}, // Pyramid (6)
788 { 2, 1, 0, 3, -1, -1} // Tet (7)
791 faceListList boundary(patchCells.size());
793 forAll(patchCells, patchI)
795 labelList& curCells = patchCells[patchI];
796 labelList& curFaces = patchCellFaces[patchI];
798 faceList& patchFaces = boundary[patchI];
799 patchFaces.setSize(curCells.size());
801 forAll (curCells, faceI)
804 cells[cellLookup[curCells[faceI] ] ].faces()
808 // this picks a cell type
809 cells[cellLookup[curCells[faceI] ] ]
812 [curFaces[faceI] - 1] // this gives a fluent face - 1
818 Info << "gambitToFoam: " << endl
819 << "Gambit file format does not provide information about the type of "
820 << "the patch (eg. wall, symmetry plane, cyclic etc)." << endl
821 << "All the patches have been created "
822 << "as type patch. Please reset after mesh conversion as necessary."
826 points *= scaleFactor;
828 wordList patchTypes(boundary.size(), polyPatch::typeName);
829 word defaultFacesName = "defaultFaces";
830 word defaultFacesType = emptyPolyPatch::typeName;
831 wordList patchPhysicalTypes(boundary.size());
837 polyMesh::defaultRegion,
845 // Mesh will auto-write on construction
850 polyMesh::defaultRegion,
864 // Set the precision of the points data to 10
865 IOstream::defaultPrecision(10);
867 Info << "Writing polyMesh" << endl;
870 Info<< nl << "End" << endl;
875 /* ------------------------------------------------------------------------- *\
876 ------ End of gambitToFoam.L
877 \* ------------------------------------------------------------------------- */