\r handling
[OpenFOAM-1.5.x.git] / applications / utilities / mesh / conversion / fluent3DMeshToFoam / fluent3DMeshToFoam.L
bloba8cb5dbb98c5fd559d4001b5b981f99057f00295
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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
25 Application
26     fluent3DMeshToFoam
28 Description
29     Converts a Fluent mesh to OpenFOAM format.
31 \*---------------------------------------------------------------------------*/
34 #undef yyFlexLexer
36  /* ------------------------------------------------------------------------ *\
37    ------ local definitions
38  \* ------------------------------------------------------------------------ */
40 #include "argList.H"
41 #include "Time.H"
42 #include "polyMesh.H"
43 #include "polyTopoChange.H"
44 #include "polyMeshZipUpCells.H"
45 #include "wallPolyPatch.H"
46 #include "symmetryPolyPatch.H"
47 #include "cyclicPolyPatch.H"
48 #include "Swap.H"
49 #include "IFstream.H"
51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 using namespace Foam;
55 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
57 // Scalae factor used to scale points (optional command line argument)
58 scalar scaleFactor = 1.0;
60 label dimensionOfGrid = 0;
61 label nPoints = 0;
62 label nFaces = 0;
63 label nCells = 0;
65 bool hangingNodes = false;
67 pointField points(0);
68 faceList faces(0);
69 labelList owner(0);
70 labelList neighbour(0);
72 // Group type and name
73 Map<word> groupType(100);
74 Map<word> groupName(100);
76 // Point groups
77 DynamicList<label> pointGroupZoneID;
78 DynamicList<label> pointGroupStartIndex;
79 DynamicList<label> pointGroupEndIndex;
81 // Face groups
82 DynamicList<label> faceGroupZoneID;
83 DynamicList<label> faceGroupStartIndex;
84 DynamicList<label> faceGroupEndIndex;
86 // Cell groups
87 DynamicList<label> cellGroupZoneID;
88 DynamicList<label> cellGroupStartIndex;
89 DynamicList<label> cellGroupEndIndex;
90 DynamicList<label> cellGroupType;
93 void uniquify(word& name, HashSet<word>& patchNames)
95     if (!patchNames.found(name))
96     {
97         patchNames.insert(name);
98     }
99     else
100     {
101         Info<< "    name " << name << " already used";
103         label i = 1;
104         word baseName = name;
106         do
107         {
108             name = baseName + "_" + Foam::name(i++);
109         } while (patchNames.found(name));
111         Info<< ", changing to " << name << endl;
112     }
116 // Dummy yywrap to keep yylex happy at compile time.
117 // It is called by yylex but is not used as the mechanism to change file.
118 // See <<EOF>>
119 #if YY_FLEX_SUBMINOR_VERSION < 34
120 extern "C" int yywrap()
121 #else
122 int yyFlexLexer::yywrap()
123 #endif
125     return 1;
130 one_space                  [ \t\f]
131 space                      {one_space}*
132 some_space                 {one_space}+
133 cspace                     ","{space}
134 nl                         (\n|\r)
135 spaceNl                    ({space}|{nl})*
137 alpha                      [_[:alpha:]]
138 digit                      [[:digit:]]
139 decDigit                   [[:digit:]]
140 octalDigit                 [0-7]
141 hexDigit                   [[:xdigit:]]
143 lbrac                      "("
144 rbrac                      ")"
145 quote                      \"
146 dash                       "-"
147 dotColonDash               [.:-]
149 schemeSpecialInitial       [!$%&*/\\:<=>?~_^#.@]
150 schemeSpecialSubsequent    [.+-]
151 schemeSymbol               (({some_space}|{alpha}|{quote}|{schemeSpecialInitial})({alpha}|{quote}|{digit}|{schemeSpecialInitial}|{schemeSpecialSubsequent})*)
154 identifier                 {alpha}({alpha}|{digit})*
155 integer                    {decDigit}+
156 label                      [1-9]{decDigit}*
157 hexLabel                   {hexDigit}+
158 zeroLabel                  {digit}*
159 signedInteger              [-+]?{integer}
160 word                       ({alpha}|{digit}|{dotColonDash})*
162 exponent_part              [eE][-+]?{digit}+
163 fractional_constant        [-+]?(({digit}*"."{digit}+)|({digit}+".")|({digit}))
165 double                     ((({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))|0)
167 x                          {double}
168 y                          {double}
169 z                          {double}
170 scalar                     {double}
171 labelListElement           {space}{zeroLabel}
172 hexLabelListElement        {space}{hexLabel}
173 scalarListElement          {space}{double}
174 schemeSymbolListElement    {space}{schemeSymbol}
175 labelList                  ({labelListElement}+{space})
176 hexLabelList               ({hexLabelListElement}+{space})
177 scalarList                 ({scalarListElement}+{space})
178 schemeSymbolList           ({schemeSymbolListElement}+{space})
180 starStar                   ("**")
181 text                       ({space}({word}*{space})*)
182 anythingInBlock            ([^)]*)
184 dateDDMMYYYY               ({digit}{digit}"/"{digit}{digit}"/"{digit}{digit}{digit}{digit})
185 dateDDMonYYYY              ((({digit}{digit}{space})|({digit}{space})){alpha}*{space}{digit}{digit}{digit}{digit})
186 time                       ({digit}{digit}":"{digit}{digit}":"{digit}{digit})
188 versionNumber              ({digit}|".")*
190 header                     {spaceNl}"(1"{some_space}
191 dimension                  {spaceNl}"(2"{some_space}
192 points                     {spaceNl}"(10"{some_space}
193 faces                      {spaceNl}"(13"{some_space}
194 cells                      {spaceNl}"(12"{some_space}
195 zoneVariant1               {spaceNl}"(39"{some_space}
196 zoneVariant2               {spaceNl}"(45"{some_space}
197 faceTree                   {spaceNl}"(59"{some_space}
199 comment                    "0"{some_space}
200 unknownPeriodicFace        "17"{some_space}
201 periodicFace               "18"{some_space}
202 cellTree                   "58"{some_space}
203 faceParents                "61"{some_space}
204 ignoreBlocks               ("4"|"37"|"38"|"41"|"60"|"64"){some_space}
206 redundantBlock             {spaceNl}({comment}|{unknownPeriodicFace}|{periodicFace}|{cellTree}|{faceParents}|{ignoreBlocks}){space}
208 endOfSection               {space}")"{space}
212  /* ------------------------------------------------------------------------ *\
213                       -----  Exclusive start states -----
214  \* ------------------------------------------------------------------------ */
216 %option stack
218 %x readHeader
219 %x readDimension
220 %x readPoint
221 %x readPointHeader
222 %x readNumberOfPoints
223 %x readPointGroupData
224 %x readPointData
225 %x readScalarList
226 %x fluentFace
227 %x readFaceHeader
228 %x readNumberOfFaces
229 %x readFaceGroupData
230 %x readFaceData
231 %x readFacesMixed
232 %x readFacesUniform
233 %x cell
234 %x readCellHeader
235 %x readNumberOfCells
236 %x readCellGroupData
237 %x readCellData
238 %x readCellsUniform
239 %x zone
240 %x readZoneHeader
241 %x readZoneGroupData
242 %x readZoneData
243 %x readZoneBlock
245 %x ignoreBlock
246 %x ignoreEmbeddedBlock
250     // End of read character pointer returned by strtol and strtod
251     char* endPtr;
253     // Point data
254     label pointGroupNumberOfComponents = 3;
255     label pointi = 0; // index used for reading points
256     label cmpt = 0;   // component index used for reading points
258     // Face data
259     label faceGroupElementType = -1;
260     label facei = 0;  // index used for reading faces
264  /* ------------------------------------------------------------------------ *\
265                             ------ Start Lexing ------
266  \* ------------------------------------------------------------------------ */
268  /*                      ------ Reading control header ------                */
270 {header} {
271         BEGIN(readHeader);
272     }
274 <readHeader>{anythingInBlock} {
275         Info<< "Header: " << YYText() << endl;
276     }
279 {dimension} {
280         BEGIN(readDimension);
281     }
283 <readDimension>{space}{label}{space} {
284         dimensionOfGrid = atoi(YYText());
285         Info<< "Dimension of grid: " << dimensionOfGrid << endl;
286     }
289 {points} {
290         BEGIN(readPointHeader);
291     }
293 <readPointHeader>{spaceNl}{lbrac}{space}"0"{space}"1"{space} {
294         BEGIN(readNumberOfPoints);
295     }
297 <readNumberOfPoints>{hexLabel}{space}{labelList} {
298         nPoints = strtol(YYText(), &endPtr, 16);
299         Info<< "Number of points: " << nPoints << endl;
300         points.setSize(nPoints);
302         // Ignore rest of stream
303     }
305 <readPointHeader>{spaceNl}{lbrac} {
306         BEGIN(readPointGroupData);
307     }
309 <readPointGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{labelList} {
310         // Read point zone-ID, start and end-label
311         // the indices will be used for checking later.
312         pointGroupZoneID.append(strtol(YYText(), &endPtr, 16));
314         // In FOAM, indices start from zero - adjust
315         pointGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
317         pointGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
319         // point group type skipped
320         strtol(endPtr, &endPtr, 16);
322         pointi = pointGroupStartIndex[pointGroupStartIndex.size()-1];
324         // reset number of components to default
325         pointGroupNumberOfComponents = 3;
327         // read number of components in the vector
328         if (endPtr < &(YYText()[YYLeng()-1]))
329         {
330             pointGroupNumberOfComponents = strtol(endPtr, &endPtr, 16);
331         }
333         Info<< "PointGroup: "
334             << pointGroupZoneID[pointGroupZoneID.size()-1]
335             << " start: "
336             << pointGroupStartIndex[pointGroupStartIndex.size()-1]
337             << " end: "
338             << pointGroupEndIndex[pointGroupEndIndex.size()-1] << flush;
339     }
341 <readNumberOfPoints,readPointGroupData>{endOfSection} {
342         BEGIN(readPointData);
343     }
345 <readPointData>{spaceNl}{lbrac}{spaceNl} {
346         Info<< ".  Reading points..." << flush;
347         cmpt = 0;
348         yy_push_state(readScalarList);
349     }
351 <readScalarList>{signedInteger}{space} {
352         points[pointi][cmpt++] = scaleFactor*atol(YYText());
353     }
355 <readScalarList>{scalar}{space} {
356         points[pointi][cmpt++] = scaleFactor*atof(YYText());
357     }
359 <readScalarList>{spaceNl} {
360         if (pointGroupNumberOfComponents == 2)
361         {
362             points[pointi].z() = 0.0;
363         }
364         cmpt = 0;
365         pointi++;
366     }
368 <readScalarList>{endOfSection} {
369         Info<< "done." << endl;
371         // check read of points
372         if (pointi != pointGroupEndIndex[pointGroupEndIndex.size()-1]+1)
373         {
374             Warning
375                 << "Problem with reading points: "
376                 << "start index: "
377                 << pointGroupStartIndex[pointGroupStartIndex.size()-1]
378                 << " end index: "
379                 << pointGroupEndIndex[pointGroupEndIndex.size()-1]
380                 << " last points read: " << pointi << endl;
381         }
383         yy_pop_state();
384     }
386 {faces} {
387         BEGIN(readFaceHeader);
388     }
390 <readFaceHeader>{spaceNl}{lbrac}{space}"0"{space}"1"{space} {
391         BEGIN(readNumberOfFaces);
392     }
394 <readNumberOfFaces>{space}{hexLabel}{space}{labelListElement}+ {
395         nFaces = strtol(YYText(), &endPtr, 16);
397         Info<< "Number of faces: " << nFaces << endl;
399         faces.setSize(nFaces);
400         owner.setSize(nFaces);
401         neighbour.setSize(nFaces);
403         // Type and element type not read
404     }
406 <readFaceHeader>{spaceNl}{lbrac} {
407         BEGIN(readFaceGroupData);
408     }
410 <readFaceGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{hexLabelListElement}+ {
411         // read fluentFace zone-ID, start and end-label
412         faceGroupZoneID.append(strtol(YYText(), &endPtr, 16));
414         // In FOAM, indices start from zero - adjust
415         faceGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
417         faceGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
419         // face group type
420         strtol(endPtr, &endPtr, 16);
422         faceGroupElementType = strtol(endPtr, &endPtr, 16);
424         facei = faceGroupStartIndex[faceGroupStartIndex.size()-1];
426         Info<< "FaceGroup: "
427             << faceGroupZoneID[faceGroupZoneID.size()-1]
428             << " start: "
429             << faceGroupStartIndex[faceGroupStartIndex.size()-1]
430             << " end: "
431             << faceGroupEndIndex[faceGroupEndIndex.size()-1] << flush;
432     }
434 <readNumberOfFaces,readFaceGroupData>{spaceNl}{endOfSection} {
435         BEGIN(readFaceData);
436     }
438 <readFaceData>{spaceNl}{lbrac} {
439         if (faceGroupElementType == 0)
440         {
441             Info<< ".  Reading mixed faces..." << flush;
442             yy_push_state(readFacesMixed);
443         }
444         else
445         {
446             Info<< ".  Reading uniform faces..." << flush;
447             yy_push_state(readFacesUniform);
448         }
449     }
451 <readFacesMixed>{spaceNl}{hexLabelList} {
452         face& curFaceLabels = faces[facei];
454         // set size of label list
455         curFaceLabels.setSize(strtol(YYText(), &endPtr, 16));
457         forAll (curFaceLabels, i)
458         {
459             curFaceLabels[i] = strtol(endPtr, &endPtr, 16) - 1;
460         }
462         // read neighbour and owner. Neighbour comes first
463         neighbour[facei] = strtol(endPtr, &endPtr, 16) - 1;
464         owner[facei] = strtol(endPtr, &endPtr, 16) - 1;
465         facei++;
466     }
468 <readFacesUniform>{spaceNl}{hexLabelList} {
469         face& curFaceLabels = faces[facei];
471         // Set size of label list.
472         curFaceLabels.setSize(faceGroupElementType);
474         curFaceLabels[0] = strtol(YYText(), &endPtr, 16) - 1;
476         for (int i=1; i<faceGroupElementType; i++)
477         {
478             curFaceLabels[i] = strtol(endPtr, &endPtr, 16) - 1;
479         }
481         // read neighbour and owner. Neighbour comes first
482         neighbour[facei] = strtol(endPtr, &endPtr, 16) - 1;
483         owner[facei] = strtol(endPtr, &endPtr, 16) - 1;
484         facei++;
485     }
487 <readFacesMixed,readFacesUniform>{spaceNl}{endOfSection} {
488         Info<< "done." << endl;
490         // check read of fluentFaces
491         if (facei != faceGroupEndIndex[faceGroupEndIndex.size()-1]+1)
492         {
493             Warning
494                 << "Problem with reading fluentFaces: "
495                 << "start index: "
496                 << faceGroupStartIndex[faceGroupStartIndex.size()-1]
497                 << " end index: "
498                 << faceGroupEndIndex[faceGroupEndIndex.size()-1]
499                 << " last fluentFaces read: " << facei << endl;
500         }
502         yy_pop_state();
503     }
506 {cells} {
507         BEGIN(readCellHeader);
508     }
510 <readCellHeader>{spaceNl}{lbrac}{space}"0"{space}"1"{space} {
511         BEGIN(readNumberOfCells);
512     }
514 <readNumberOfCells>{space}{hexLabel}{space}{labelListElement}+ {
515         nCells = strtol(YYText(), &endPtr, 16);
516         Info<< "Number of cells: " << nCells << endl;
517     }
519 <readCellHeader>{spaceNl}{lbrac} {
520         BEGIN(readCellGroupData);
521     }
523 <readCellGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel} {
524         // Warning. This entry must be above the next one because of the lexing
525         // rules. It is introduced to deal with the problem of reading
526         // non-standard cell definition from Tgrid, which misses the type label.
528         Warning
529             << "Tgrid syntax problem: " << YYText() << endl;
531         // read cell zone-ID, start and end-label
532         cellGroupZoneID.append(strtol(YYText(), &endPtr, 16));
534         // the indices will be used for checking later.
535         cellGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
537         cellGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
539         cellGroupType.append(strtol(endPtr, &endPtr, 16));
541         Info<< "CellGroup: "
542             << cellGroupZoneID[cellGroupZoneID.size()-1]
543             << " start: "
544             << cellGroupStartIndex[cellGroupStartIndex.size()-1]
545             << " end: "
546             << cellGroupEndIndex[cellGroupEndIndex.size()-1]
547             << " type: "
548             << cellGroupType[cellGroupType.size()-1]
549             << endl;
550     }
552 <readCellGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel} {
553         // Warning. See above
555         // read cell zone-ID, start and end-label
556         cellGroupZoneID.append(strtol(YYText(), &endPtr, 16));
558         // the indices will be used for checking later.
559         cellGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
561         cellGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
563         cellGroupType.append(strtol(endPtr, &endPtr, 16));
565         // Note. Potentially skip cell set if type is zero.
566         strtol(endPtr, &endPtr, 16);
568         Info<< "CellGroup: "
569             << cellGroupZoneID[cellGroupZoneID.size()-1]
570             << " start: "
571             << cellGroupStartIndex[cellGroupStartIndex.size()-1]
572             << " end: "
573             << cellGroupEndIndex[cellGroupEndIndex.size()-1]
574             << " type: "
575             << cellGroupType[cellGroupType.size()-1]
576             << endl;
577     }
579 <readNumberOfCells,readCellGroupData>{endOfSection} {
580         BEGIN(readCellData);
581     }
583 <readCellData>{spaceNl}{lbrac} {
584         // Quickly scan to the end of the cell data block and discard
585         register int c;
586         while ((c = yyinput()) != 0 && c != ')')
587         {}
588     }
590 {faceTree} {
591         // There are hanging nodes in the mesh so make sure it gets zipped-up
592         hangingNodes = true;
593         yy_push_state(ignoreBlock);
594     }
596 {zoneVariant1} {
597         BEGIN(readZoneHeader);
598     }
600 {zoneVariant2} {
601         BEGIN(readZoneHeader);
602     }
604 <readZoneHeader>{spaceNl}{lbrac} {
605         BEGIN(readZoneGroupData);
606     }
608 <readZoneGroupData>{space}{label}{space}{word}{space}{word}{space}{label}? {
609         IStringStream zoneDataStream(YYText());
611         // cell zone-ID not in hexadecimal!!! Inconsistency
612         label zoneID(readLabel(zoneDataStream));
614         groupType.insert(zoneID, word(zoneDataStream));
615         groupName.insert(zoneID, word(zoneDataStream));
617         Info<< "Zone: " << zoneID
618             << " name: " << groupName[zoneID]
619             << " type: " << groupType[zoneID] << flush;
620     }
622 <readZoneGroupData>{endOfSection} {
623         BEGIN(readZoneData);
624     }
626 <readZoneData>{spaceNl}{lbrac} {
627         Info<< ".  Reading zone data..." << flush;
628         yy_push_state(readZoneBlock);
629     }
631 <readZoneBlock>{spaceNl}{schemeSymbolList} {
632     }
634 <readZoneBlock>{lbrac} {
635         Warning
636             << "Found unknown block in zone: " << YYText() << endl;
637         yy_push_state(ignoreBlock);
638     }
640 <readZoneBlock>{endOfSection} {
641         Info<< "done." << endl;
642         yy_pop_state();
643     }
647  /*             ------ Reading end of section and others ------              */
649 <readHeader,readDimension,readPointData,readFaceData,readCellData,readZoneData>{spaceNl}{endOfSection} {
650         BEGIN(INITIAL);
651     }
653  /*    ------ Reading unknown type or non-standard comment ------            */
655 {lbrac}{label} {
656         Warning
657             << "Found unknown block of type: "
658             << Foam::string(YYText())(1, YYLeng()-1) << endl;
660         yy_push_state(ignoreBlock);
661     }
663 {lbrac}{redundantBlock} {
664         yy_push_state(ignoreBlock);
665     }
667 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{quote}{text}{quote} {
668     }
670 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{schemeSymbol} {
671     }
673 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{lbrac} {
674         yy_push_state(ignoreEmbeddedBlock);
676     }
678 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{endOfSection} {
679         yy_pop_state();
680     }
682 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{labelList} {
683     }
685 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{hexLabelList} {
686     }
688 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{scalarList} {
689     }
691 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{schemeSymbolList} {
692     }
694 <ignoreBlock,ignoreEmbeddedBlock>{spaceNl}{text} {
695     }
698  /* ------              Ignore remaining space and \n s.             ------  */
700 <*>{some_space}|\n|\r {
701     }
704  /* ------              Any other characters are errors.              ------ */
706 <*>. {
707         // This is a catch all.
708         FatalErrorIn("fluentMeshToFoam::lexer")
709             << "Do not understand characters: " << YYText()
710             << exit(FatalError);
711     }
714  /*  ------ On EOF return to previous file, if none exists terminate. ------ */
716 <<EOF>> {
717             yyterminate();
718     }
721 int main(int argc, char *argv[])
723     argList::noParallel();
724     argList::validArgs.append("Fluent mesh file");
725     argList::validOptions.insert("scale", "scale factor");
726     argList::validOptions.insert("ignoreCellGroups", "cell group names");
727     argList::validOptions.insert("ignoreFaceGroups", "face group names");
729     argList args(argc, argv);
731     if (!args.check())
732     {
733         FatalError.exit();
734     }
736     if (args.options().found("scale"))
737     {
738         scaleFactor = atof(args.options()["scale"].c_str());
739     }
741     HashSet<word> ignoreCellGroups;
742     if (args.options().found("ignoreCellGroups"))
743     {
744         IStringStream(args.options()["ignoreCellGroups"])() >> ignoreCellGroups;
745     }
747     HashSet<word> ignoreFaceGroups;
748     if (args.options().found("ignoreFaceGroups"))
749     {
750         IStringStream(args.options()["ignoreFaceGroups"])() >> ignoreFaceGroups;
751     }
753 #   include "createTime.H"
755     fileName fluentFile(args.additionalArgs()[0]);
756     IFstream fluentStream(fluentFile);
758     if (!fluentStream)
759     {
760         FatalErrorIn(args.executable())
761             << ": file " << fluentFile << " not found"
762             << exit(FatalError);
763     }
765     yyFlexLexer lexer(&fluentStream.stdStream());
767     while(lexer.yylex() != 0)
768     {}
770     Info<< "\nFINISHED LEXING\n\n";
772     if (dimensionOfGrid != 3)
773     {
774         FatalErrorIn(args.executable())
775             << "Mesh is not 3D, dimension of grid: " << dimensionOfGrid
776             << exit(FatalError);
777     }
779     pointGroupZoneID.shrink();
780     pointGroupStartIndex.shrink();
781     pointGroupEndIndex.shrink();
783     faceGroupZoneID.shrink();
784     faceGroupStartIndex.shrink();
785     faceGroupEndIndex.shrink();
787     cellGroupZoneID.shrink();
788     cellGroupStartIndex.shrink();
789     cellGroupEndIndex.shrink();
790     cellGroupType.shrink();
793     // Pre-filtering: flip "owner" boundary or wrong oriented internal
794     // faces and move to neighbour
795     forAll (faces, facei)
796     {
797         if
798         (
799             owner[facei] == -1
800          || (neighbour[facei] != -1 && owner[facei] > neighbour[facei])
801         )
802         {
803             faces[facei] = faces[facei].reverseFace();
804             Swap(owner[facei], neighbour[facei]);
805         }
806     }
809     // Foam type for Fluent type
810     // ~~~~~~~~~~~~~~~~~~~~~~~~~
812     HashTable<word> fluentToFoamType;
814     fluentToFoamType.insert("pressure", polyPatch::typeName);
815     fluentToFoamType.insert("pressure-inlet", polyPatch::typeName);
816     fluentToFoamType.insert("inlet-vent", polyPatch::typeName);
817     fluentToFoamType.insert("intake-fan", polyPatch::typeName);
818     fluentToFoamType.insert("pressure-outlet", polyPatch::typeName);
819     fluentToFoamType.insert("exhaust-fan", polyPatch::typeName);
820     fluentToFoamType.insert("outlet-vent", polyPatch::typeName);
821     fluentToFoamType.insert("pressure-far-field", polyPatch::typeName);
822     fluentToFoamType.insert("velocity-inlet", polyPatch::typeName);
823     fluentToFoamType.insert("mass-flow-inlet", polyPatch::typeName);
824     fluentToFoamType.insert("outflow", polyPatch::typeName);
826     fluentToFoamType.insert("wall" , wallPolyPatch::typeName);
828     fluentToFoamType.insert("symmetry",  symmetryPolyPatch::typeName);
829     fluentToFoamType.insert("axis",  symmetryPolyPatch::typeName);
831     fluentToFoamType.insert("interior", polyPatch::typeName);
832     fluentToFoamType.insert("interface", polyPatch::typeName);
833     fluentToFoamType.insert("internal", polyPatch::typeName);
834     fluentToFoamType.insert("solid", polyPatch::typeName);
835     fluentToFoamType.insert("fan", cyclicPolyPatch::typeName);
836     fluentToFoamType.insert("radiator", polyPatch::typeName);
837     fluentToFoamType.insert("porous-jump", polyPatch::typeName);
840     // Foam patch type for Fluent zone type
841     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
843     HashSet<word> fluentGroupToFoamPatch;
844     fluentGroupToFoamPatch.insert("wall");
845     fluentGroupToFoamPatch.insert("fan");
848     // Create intial empty polyMesh
849     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
851     polyMesh mesh
852     (
853         IOobject
854         (
855             polyMesh::defaultRegion,
856             runTime.constant(),
857             runTime
858         ),
859         pointField(0),
860         faceList(0),
861         labelList(0),
862         labelList(0)
863     );
866     // Check the cell groups for zones ignoring those in ignoreCellGroups
867     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
868     label nCellZones = 0;
869     labelList cellZoneIDs(cellGroupZoneID.size());
871     forAll(cellGroupZoneID, cgi)
872     {
873         if (!ignoreCellGroups.found(groupName[cellGroupZoneID[cgi] ]))
874         {
875             cellZoneIDs[nCellZones++] = cgi;
876         }
877     }
879     cellZoneIDs.setSize(nCellZones);
882     // Check the face groups for boundary patches, baffles and faceZones
883     // ignoring the interior zones in ignoreCellGroups
884     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
885     label nPatches = 0;
886     labelList patchIDs(faceGroupZoneID.size());
888     label nFaceZones = 0;
889     labelList faceZoneIDs(faceGroupZoneID.size());
891     forAll(faceGroupZoneID, fgi)
892     {
893         label zoneID = faceGroupZoneID[fgi];
894         label start = faceGroupStartIndex[fgi];
896         if (groupType.found(zoneID))
897         {
898             const word& type = groupType[zoneID];
900             // Check the first element of neighbour for boundary group
901             if (neighbour[start] == -1 || fluentGroupToFoamPatch.found(type))
902             {
903                 patchIDs[nPatches++] = fgi;
904             }
905             else
906             {
907                 if (!ignoreFaceGroups.found(groupName[faceGroupZoneID[fgi] ]))
908                 {
909                     faceZoneIDs[nFaceZones++] = fgi;
910                 }
911             }
912         }
913         else if (hangingNodes)
914         {
915             label end = faceGroupEndIndex[fgi];
917             Info<< "Unknown FaceGroup " << zoneID
918                 << " assumed to be parent faces of refinement "
919                    "patterns and ignored."
920                 << endl;
922             // Set the owner of these faces to -1 so that they do not get
923             // added to the mesh
924             for(label facei = start; facei <= end; facei++)
925             {
926                 owner[facei] = -1;
927             }
928         }
929         else
930         {
931             FatalErrorIn(args.executable())
932                 << "Unknown FaceGroup " << zoneID << " not in a zone"
933                 << exit(FatalError);
934         }
935     }
937     patchIDs.setSize(nPatches);
938     faceZoneIDs.setSize(nFaceZones);
941     // Add empty patches
942     // ~~~~~~~~~~~~~~~~~
944     List<polyPatch*> newPatches(nPatches);
945     HashSet<word> patchNames;
947     forAll(patchIDs, patchi)
948     {
949         label zoneID = faceGroupZoneID[patchIDs[patchi] ];
950         word name = groupName[zoneID];
951         const word& type = groupType[zoneID];
953         Info<< "Creating patch " << patchi
954             << " for zone: " << zoneID
955             << " name: " << name
956             << " type: " << type
957             << endl;
959         uniquify(name, patchNames);
961         HashTable<word>::const_iterator iter = fluentToFoamType.find(type);
963         if (iter != fluentToFoamType.end())
964         {
965             newPatches[patchi] = polyPatch::New
966             (
967                 iter(),
968                 name,
969                 0,
970                 0,
971                 patchi,
972                 mesh.boundaryMesh()
973             ).ptr();
974         }
975         else
976         {
977             Info<< "Adding polyPatch for unknown Fluent type " << type
978                 << endl;
980             newPatches[patchi] = new polyPatch
981             (
982                 name,
983                 0,
984                 0,
985                 patchi,
986                 mesh.boundaryMesh()
987             );
988         }
989     }
990     mesh.addPatches(newPatches);
993     // Add empty zones
994     // ~~~~~~~~~~~~~~~
996     // Cell zones
997     mesh.cellZones().setSize(cellZoneIDs.size());
998     HashSet<word> cellZoneNames;
1000     forAll(cellZoneIDs, cellZonei)
1001     {
1002         label zoneID = cellGroupZoneID[cellZoneIDs[cellZonei] ];
1003         word name = groupName[zoneID];
1004         const word& type = groupType[zoneID];
1006         Info<< "Creating cellZone " << cellZonei
1007             << " name: " << name
1008             << " type: " << type
1009             << endl;
1011         uniquify(name, cellZoneNames);
1013         mesh.cellZones().set
1014         (
1015             cellZonei,
1016             new cellZone
1017             (
1018                 name,
1019                 labelList(0),
1020                 cellZonei,
1021                 mesh.cellZones()
1022             )
1023         );
1024     }
1026     // Face zones
1027     mesh.faceZones().setSize(nFaceZones);
1028     HashSet<word> faceZoneNames;
1030     forAll(faceZoneIDs, faceZonei)
1031     {
1032         label zoneID = faceGroupZoneID[faceZoneIDs[faceZonei] ];
1033         word name = groupName[zoneID];
1034         const word& type = groupType[zoneID];
1036         Info<< "Creating faceZone " << faceZonei
1037             << " name: " << name
1038             << " type: " << type
1039             << endl;
1041         uniquify(name, faceZoneNames);
1043         mesh.faceZones().set
1044         (
1045             faceZonei,
1046             new faceZone
1047             (
1048                 name,
1049                 labelList(0),
1050                 boolList(0),
1051                 faceZonei,
1052                 mesh.faceZones()
1053             )
1054         );
1055     }
1058     // Modify mesh for points/cells/faces
1059     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1061     // Mesh-change container
1062     polyTopoChange meshMod(mesh, false);
1064     // Add all points
1065     forAll(points, pointi)
1066     {
1067         meshMod.addPoint(points[pointi], pointi, -1, true);
1068     }
1069     points.setSize(0);
1071     // Add all cells
1072     for (label celli = 0; celli < nCells; celli++)
1073     {
1074         meshMod.addCell
1075         (
1076             -1,         // masterPointID
1077             -1,         // masterEdgeID
1078             -1,         // masterFaceID
1079             celli,      // masterCellID
1080             -1          // zoneID
1081         );
1082     }
1084     // Modify cells to be in zones as required
1085     forAll(cellZoneIDs, cellZonei)
1086     {
1087         label cgi = cellZoneIDs[cellZonei];
1089         for
1090         (
1091             label celli = cellGroupStartIndex[cgi];
1092             celli <= cellGroupEndIndex[cgi];
1093             celli++
1094         )
1095         {
1096             meshMod.modifyCell(celli, cellZonei);
1097         }
1098     }
1101     // Add faceZone faces
1102     forAll(faceZoneIDs, faceZonei)
1103     {
1104         label fgi = faceZoneIDs[faceZonei];
1105         label start = faceGroupStartIndex[fgi];
1106         label end = faceGroupEndIndex[fgi];
1107         label zoneID = faceGroupZoneID[fgi];
1109         Info<< "faceZone from Fluent indices: " << start
1110             << " to: " << end
1111             << " type: " << groupType[zoneID]
1112             << endl;
1114         for (label facei = start; facei <= end; facei++)
1115         {
1116             meshMod.addFace
1117             (
1118                 faces[facei],
1119                 owner[facei],
1120                 neighbour[facei],
1121                 -1,                 // masterPointID
1122                 -1,                 // masterEdgeID
1123                 facei,              // masterFace
1124                 false,              // flipFaceFlux
1125                 -1,                 // patchID
1126                 faceZonei,          // zoneID
1127                 false               // zoneFlip
1128             );
1130             // Mark face as being done
1131             owner[facei] = -1;
1132         }
1133     }
1135     // Add patch faces
1136     forAll(patchIDs, patchi)
1137     {
1138         label fgi = patchIDs[patchi];
1139         label start = faceGroupStartIndex[fgi];
1140         label end = faceGroupEndIndex[fgi];
1141         label zoneID = faceGroupZoneID[fgi];
1143         Info<< "patch " << patchi << " from Fluent indices: " << start
1144             << " to: " << end
1145             << " type: " << groupType[zoneID]
1146             << endl;
1148         for (label facei = start; facei <= end; facei++)
1149         {
1150             meshMod.addFace
1151             (
1152                 faces[facei],
1153                 owner[facei],
1154                 -1,
1155                 -1,                 // masterPointID
1156                 -1,                 // masterEdgeID
1157                 facei,              // masterFace
1158                 false,              // flipFaceFlux
1159                 patchi,             // patchID
1160                 -1,                 // zoneID
1161                 false               // zoneFlip
1162             );
1164             // For baffles create the opposite face
1165             if (neighbour[start] != -1)
1166             {
1167                 meshMod.addFace
1168                 (
1169                     faces[facei].reverseFace(),
1170                     neighbour[facei],
1171                     -1,
1172                     -1,                 // masterPointID
1173                     -1,                 // masterEdgeID
1174                     facei,              // masterFace
1175                     false,              // flipFaceFlux
1176                     patchi,             // patchID
1177                     -1,                 // zoneID
1178                     false               // zoneFlip
1179                 );
1180             }
1182             // Mark face as being done
1183             owner[facei] = -1;
1184         }
1185     }
1187     // Add remaining internal faces
1188     forAll(owner, facei)
1189     {
1190         if (owner[facei] != -1)
1191         {
1192             // Check the face being added as an internal face actually is one
1193             if (neighbour[facei] == -1)
1194             {
1195                 FatalErrorIn(args.executable())
1196                     << "Attempt of add internal face " << facei
1197                     << " which is a boundary face"
1198                     << exit(FatalError);
1199             }
1201             meshMod.addFace
1202             (
1203                 faces[facei],
1204                 owner[facei],
1205                 neighbour[facei],
1206                 -1,                 //masterPointID
1207                 -1,                 //masterEdgeID
1208                 facei,              //masterFace
1209                 false,              //flipFaceFlux
1210                 -1,                 //patchID
1211                 -1,                 //zoneID
1212                 false               //zoneFlip
1213             );
1214         }
1215     }
1217     // Reclaim storage
1218     faces.setSize(0);
1219     owner.setSize(0);
1220     neighbour.setSize(0);
1223     // Modify mesh
1224     // ~~~~~~~~~~~
1226     autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
1228     // Zip-up the mesh if it contained hanging nodes
1229     if (hangingNodes)
1230     {
1231         Info<< "Zipping mesh to remove hanging nodes" << endl;
1232         polyMeshZipUpCells(mesh);
1233     }
1235     mesh.setInstance(runTime.constant());
1237     // Set the precision of the points data to 10
1238     IOstream::defaultPrecision(10);
1240     Info<< nl << "Writing mesh to " << mesh.objectPath() << endl;
1241     mesh.write();
1244     Info<< nl << "End" << endl;
1245     return 0;
1249  /* ------------------------------------------------------------------------ *\
1250     ------ End of fluentMeshToFoam.L
1251  \* ------------------------------------------------------------------------ */