1 /*--------------------------------*- C++ -*----------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
28 Converts a Fluent mesh to FOAM format.
30 \*---------------------------------------------------------------------------*/
35 /* ------------------------------------------------------------------------ *\
36 ------ local definitions
37 \* ------------------------------------------------------------------------ */
40 #include "objectRegistry.H"
43 #include "directTopoChange.H"
44 #include "polyMeshZipUpCells.H"
45 #include "wallPolyPatch.H"
46 #include "symmetryPolyPatch.H"
47 #include "cyclicPolyPatch.H"
50 #include "wordIOList.H"
51 #include "readHexLabel.H"
53 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
57 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
62 // Scale factor used to scale points (optional command line argument)
63 scalar scaleFactor = 1.0;
65 label dimensionOfGrid = 0;
70 bool hangingNodes = false;
75 labelList neighbour(0);
77 // Group type and name
78 Map<word> groupType(100);
79 Map<word> groupName(100);
82 DynamicList<label> pointGroupZoneID;
83 DynamicList<label> pointGroupStartIndex;
84 DynamicList<label> pointGroupEndIndex;
87 DynamicList<label> faceGroupZoneID;
88 DynamicList<label> faceGroupStartIndex;
89 DynamicList<label> faceGroupEndIndex;
92 DynamicList<label> cellGroupZoneID;
93 DynamicList<label> cellGroupStartIndex;
94 DynamicList<label> cellGroupEndIndex;
95 DynamicList<label> cellGroupType;
97 // Special parsing of (incorrect) Cubit files
98 bool cubitFile = false;
101 void uniquify(word& name, HashSet<word>& patchNames)
103 if (!patchNames.found(name))
105 patchNames.insert(name);
109 Info<< " name " << name << " already used";
112 word baseName = name;
116 name = baseName + "_" + Foam::name(i++);
117 } while (patchNames.found(name));
119 Info<< ", changing to " << name << endl;
124 // Dummy yywrap to keep yylex happy at compile time.
125 // It is called by yylex but is not used as the mechanism to change file.
127 #if YY_FLEX_MINOR_VERSION < 6 && YY_FLEX_SUBMINOR_VERSION < 34
128 extern "C" int yywrap()
130 int yyFlexLexer::yywrap()
140 some_space {one_space}+
147 hexDigit [[:xdigit:]]
155 schemeSpecialInitial [!$%&*/\\:<=>?~_^#.@']
156 schemeSpecialSubsequent [.+-]
157 schemeSymbol (({some_space}|{alpha}|{quote}|{schemeSpecialInitial})({alpha}|{quote}|{digit}|{schemeSpecialInitial}|{schemeSpecialSubsequent})*)
160 identifier {alpha}({alpha}|{digit})*
162 label [1-9]{decDigit}*
165 signedInteger [-+]?{integer}
166 word ({alpha}|{digit}|{dotColonDash})*
168 exponent_part [eE][-+]?{digit}+
169 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+".")|({digit}))
171 double ((({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))|0)
177 labelListElement {space}{zeroLabel}
178 hexLabelListElement {space}{hexLabel}
179 scalarListElement {space}{double}
180 schemeSymbolListElement {space}{schemeSymbol}
181 labelList ({labelListElement}+{space})
182 hexLabelList ({hexLabelListElement}+{space})
183 scalarList ({scalarListElement}+{space})
184 schemeSymbolList ({schemeSymbolListElement}+{space})
187 text ({space}({word}*{space})*)
188 anythingInBlock ([^)]*)
189 gridgenComment (({space}|{cspace})({word}*{space})*)
191 dateDDMMYYYY ({digit}{digit}"/"{digit}{digit}"/"{digit}{digit}{digit}{digit})
192 dateDDMonYYYY ((({digit}{digit}{space})|({digit}{space})){alpha}*{space}{digit}{digit}{digit}{digit})
193 time ({digit}{digit}":"{digit}{digit}":"{digit}{digit})
195 versionNumber ({digit}|".")*
197 header {space}"(1"{space}
198 dimension {space}"(2"{space}
199 points {space}"(10"{space}
200 faces {space}"(13"{space}
201 cells {space}"(12"{space}
202 zoneVariant1 {space}"(39"{space}
203 zoneVariant2 {space}"(45"{space}
204 faceTree {space}"(59"{space}
207 unknownPeriodicFace "17"{space}
208 periodicFace "18"{space}
210 faceParents "61"{space}
211 ignoreBlocks ("4"|"37"|"38"|"40"|"41"|"60"|"64"){space}
213 redundantBlock {space}({comment}|{unknownPeriodicFace}|{periodicFace}|{cellTree}|{faceParents}|{ignoreBlocks}){space}
215 endOfSection {space}")"{space}
219 /* ------------------------------------------------------------------------ *\
220 ----- Exclusive start states -----
221 \* ------------------------------------------------------------------------ */
229 %x readNumberOfPoints
230 %x readPointGroupData
253 %x ignoreEmbeddedBlock
257 // End of read character pointer returned by strtol and strtod
261 label pointGroupNumberOfComponents = 3;
262 label pointi = 0; // index used for reading points
263 label cmpt = 0; // component index used for reading points
266 label faceGroupElementType = -1;
267 label facei = 0; // index used for reading faces
271 /* ------------------------------------------------------------------------ *\
272 ------ Start Lexing ------
273 \* ------------------------------------------------------------------------ */
275 /* ------ Reading control header ------ */
281 <readHeader>{anythingInBlock} {
282 Info<< "Header: " << YYText() << endl;
287 BEGIN(readDimension);
290 <readDimension>{space}{label}{space} {
291 dimensionOfGrid = atoi(YYText());
292 Info<< "Dimension of grid: " << dimensionOfGrid << endl;
297 BEGIN(readPointHeader);
300 <readPointHeader>{space}{lbrac}{space}"0"{space}"1"{space} {
301 BEGIN(readNumberOfPoints);
304 <readNumberOfPoints>{hexLabel}{space}{labelList} {
305 nPoints = strtol(YYText(), &endPtr, 16);
306 Info<< "Number of points: " << nPoints << endl;
307 points.setSize(nPoints);
309 // Ignore rest of stream
312 <readPointHeader>{space}{lbrac} {
313 BEGIN(readPointGroupData);
316 <readPointGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{labelList} {
317 // Read point zone-ID, start and end-label
318 // the indices will be used for checking later.
319 pointGroupZoneID.append(strtol(YYText(), &endPtr, 16));
321 // In FOAM, indices start from zero - adjust
322 pointGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
324 pointGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
326 // point group type skipped
327 strtol(endPtr, &endPtr, 16);
329 pointi = pointGroupStartIndex[pointGroupStartIndex.size()-1];
331 // reset number of components to default
332 pointGroupNumberOfComponents = 3;
334 // read number of components in the vector
335 if (endPtr < &(YYText()[YYLeng()-1]))
337 pointGroupNumberOfComponents = strtol(endPtr, &endPtr, 16);
340 Info<< "PointGroup: "
341 << pointGroupZoneID[pointGroupZoneID.size()-1]
343 << pointGroupStartIndex[pointGroupStartIndex.size()-1]
345 << pointGroupEndIndex[pointGroupEndIndex.size()-1]
346 << " nComponents: " << pointGroupNumberOfComponents << flush;
349 <readNumberOfPoints,readPointGroupData>{endOfSection} {
350 BEGIN(readPointData);
353 <readPointData>{space}{lbrac}{space} {
354 Info<< ". Reading points..." << flush;
356 yy_push_state(readScalarList);
359 <readScalarList>{signedInteger}{space} {
360 points[pointi][cmpt++] = scaleFactor*atol(YYText());
362 if (cmpt == pointGroupNumberOfComponents)
364 if (pointGroupNumberOfComponents == 2)
366 points[pointi].z() = 0.0;
374 <readScalarList>{scalar}{space} {
375 points[pointi][cmpt++] = scaleFactor*atof(YYText());
377 if (cmpt == pointGroupNumberOfComponents)
379 if (pointGroupNumberOfComponents == 2)
381 points[pointi].z() = 0.0;
389 <readScalarList>{endOfSection} {
390 Info<< "done." << endl;
392 // check read of points
393 if (pointi != pointGroupEndIndex[pointGroupEndIndex.size()-1]+1)
396 << "Problem with reading points: " << nl
398 << pointGroupStartIndex[pointGroupStartIndex.size()-1]
400 << pointGroupEndIndex[pointGroupEndIndex.size()-1]
401 << " last points read: " << pointi << nl
402 << " on line " << lineNo << endl;
409 BEGIN(readFaceHeader);
412 <readFaceHeader>{space}{lbrac}{space}"0"{space}"1"{space} {
413 BEGIN(readNumberOfFaces);
416 <readNumberOfFaces>{space}{hexLabel}{space}{labelListElement}+ {
417 nFaces = strtol(YYText(), &endPtr, 16);
419 Info<< "Number of faces: " << nFaces << endl;
421 faces.setSize(nFaces);
422 owner.setSize(nFaces);
423 neighbour.setSize(nFaces);
425 // Type and element type not read
428 <readFaceHeader>{space}{lbrac} {
429 BEGIN(readFaceGroupData);
432 <readFaceGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{hexLabelListElement}+ {
433 // read fluentFace zone-ID, start and end-label
434 faceGroupZoneID.append(strtol(YYText(), &endPtr, 16));
436 // In FOAM, indices start from zero - adjust
437 faceGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
439 faceGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
442 strtol(endPtr, &endPtr, 16);
444 faceGroupElementType = strtol(endPtr, &endPtr, 16);
446 facei = faceGroupStartIndex[faceGroupStartIndex.size()-1];
449 << faceGroupZoneID[faceGroupZoneID.size()-1]
451 << faceGroupStartIndex[faceGroupStartIndex.size()-1]
453 << faceGroupEndIndex[faceGroupEndIndex.size()-1] << flush;
456 <readNumberOfFaces,readFaceGroupData>{space}{endOfSection} {
460 <readFaceData>{space}{lbrac} {
461 if (faceGroupElementType == 0 || faceGroupElementType > 4)
463 Info<< ". Reading mixed faces..." << flush;
464 yy_push_state(readFacesMixed);
468 Info<< ". Reading uniform faces..." << flush;
469 yy_push_state(readFacesUniform);
473 <readFacesMixed>{space}{hexLabelList} {
474 face& curFaceLabels = faces[facei];
476 // set size of label list
477 curFaceLabels.setSize(strtol(YYText(), &endPtr, 16));
479 forAll (curFaceLabels, i)
481 curFaceLabels[i] = strtol(endPtr, &endPtr, 16) - 1;
484 // read neighbour and owner. Neighbour comes first
485 neighbour[facei] = strtol(endPtr, &endPtr, 16) - 1;
486 owner[facei] = strtol(endPtr, &endPtr, 16) - 1;
490 <readFacesUniform>{space}{hexLabelList} {
491 face& curFaceLabels = faces[facei];
493 // Set size of label list.
494 curFaceLabels.setSize(faceGroupElementType);
496 curFaceLabels[0] = strtol(YYText(), &endPtr, 16) - 1;
498 for (int i=1; i<faceGroupElementType; i++)
500 curFaceLabels[i] = strtol(endPtr, &endPtr, 16) - 1;
503 // read neighbour and owner. Neighbour comes first
504 neighbour[facei] = strtol(endPtr, &endPtr, 16) - 1;
505 owner[facei] = strtol(endPtr, &endPtr, 16) - 1;
509 <readFacesMixed,readFacesUniform>{space}{endOfSection} {
510 Info<< "done." << endl;
512 // check read of fluentFaces
513 if (facei != faceGroupEndIndex[faceGroupEndIndex.size()-1]+1)
516 << "Problem with reading fluentFaces: " << nl
518 << faceGroupStartIndex[faceGroupStartIndex.size()-1]
520 << faceGroupEndIndex[faceGroupEndIndex.size()-1]
521 << " last fluentFaces read: " << facei << nl
522 << " on line " << lineNo << endl;
530 BEGIN(readCellHeader);
533 <readCellHeader>{space}{lbrac}{space}"0"{space}"1"{space} {
534 BEGIN(readNumberOfCells);
537 <readNumberOfCells>{space}{hexLabel}{space}{labelListElement}+ {
538 nCells = strtol(YYText(), &endPtr, 16);
539 Info<< "Number of cells: " << nCells << endl;
542 <readCellHeader>{space}{lbrac} {
543 BEGIN(readCellGroupData);
546 <readCellGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel} {
547 // Warning. This entry must be above the next one because of the lexing
548 // rules. It is introduced to deal with the problem of reading
549 // non-standard cell definition from Tgrid, which misses the type label.
552 << "Tgrid syntax problem: " << YYText() << nl
553 << " on line " << lineNo << endl;
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));
566 << cellGroupZoneID[cellGroupZoneID.size()-1]
568 << cellGroupStartIndex[cellGroupStartIndex.size()-1]
570 << cellGroupEndIndex[cellGroupEndIndex.size()-1]
572 << cellGroupType[cellGroupType.size()-1]
576 <readCellGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel} {
577 // Warning. See above
579 // read cell zone-ID, start and end-label
580 cellGroupZoneID.append(strtol(YYText(), &endPtr, 16));
582 // the indices will be used for checking later.
583 cellGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
585 cellGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
587 cellGroupType.append(strtol(endPtr, &endPtr, 16));
589 // Note. Potentially skip cell set if type is zero.
590 strtol(endPtr, &endPtr, 16);
593 << cellGroupZoneID[cellGroupZoneID.size()-1]
595 << cellGroupStartIndex[cellGroupStartIndex.size()-1]
597 << cellGroupEndIndex[cellGroupEndIndex.size()-1]
599 << cellGroupType[cellGroupType.size()-1]
603 <readNumberOfCells,readCellGroupData>{endOfSection} {
607 <readCellData>{space}{lbrac} {
608 // Quickly scan to the end of the cell data block and discard
610 while ((c = yyinput()) != 0 && c != ')')
615 // There are hanging nodes in the mesh so make sure it gets zipped-up
617 yy_push_state(ignoreBlock);
621 BEGIN(readZoneHeader);
625 BEGIN(readZoneHeader);
628 <readZoneHeader>{space}{lbrac} {
629 BEGIN(readZoneGroupData);
632 <readZoneGroupData>{space}{hexLabel}{space}{word}{space}{word}{space}{label}? {
633 IStringStream zoneDataStream(YYText());
635 // cell zone-ID not in hexadecimal!!! Inconsistency
640 zoneID = readHexLabel(zoneDataStream);
644 zoneID = readLabel(zoneDataStream);
647 groupType.insert(zoneID, word(zoneDataStream));
648 groupName.insert(zoneID, word(zoneDataStream));
650 Info<< "Zone: " << zoneID
651 << " name: " << groupName[zoneID]
652 << " type: " << groupType[zoneID] << flush;
655 <readZoneGroupData>{endOfSection} {
659 <readZoneData>{space}{lbrac} {
660 Info<< ". Reading zone data..." << flush;
661 yy_push_state(readZoneBlock);
664 <readZoneBlock>{space}{schemeSymbolList} {
667 <readZoneBlock>{lbrac} {
669 // << "Found unknown block in zone: " << YYText() << nl
670 // << " on line " << lineNo << endl;
671 yy_push_state(ignoreBlock);
674 <readZoneBlock>{endOfSection} {
675 Info<< "done." << endl;
681 /* ------ Reading end of section and others ------ */
683 <readHeader,readDimension,readPointData,readFaceData,readCellData,readZoneData>{space}{endOfSection} {
687 /* ------ Reading unknown type or non-standard comment ------ */
691 << "Found unknown block of type: "
692 << Foam::string(YYText())(1, YYLeng()-1) << nl
693 << " on line " << lineNo << endl;
695 yy_push_state(ignoreBlock);
698 {lbrac}{redundantBlock} {
699 yy_push_state(ignoreBlock);
702 <ignoreBlock,ignoreEmbeddedBlock>{space}{quote}{text}{quote} {
705 <ignoreBlock,ignoreEmbeddedBlock>{space}{schemeSymbol} {
708 <ignoreBlock,ignoreEmbeddedBlock>{space}{lbrac} {
709 yy_push_state(ignoreEmbeddedBlock);
713 <ignoreBlock,ignoreEmbeddedBlock>{space}{endOfSection} {
717 <ignoreBlock,ignoreEmbeddedBlock>{space}{labelList} {
720 <ignoreBlock,ignoreEmbeddedBlock>{space}{hexLabelList} {
723 <ignoreBlock,ignoreEmbeddedBlock>{space}{scalarList} {
726 <ignoreBlock,ignoreEmbeddedBlock>{space}{schemeSymbolList} {
729 <ignoreBlock,ignoreEmbeddedBlock>{space}{text} {
732 <ignoreBlock,ignoreEmbeddedBlock>{gridgenComment} {
736 /* ------ Count newlines. ------ */
743 /* ------ Ignore remaining space. ------ */
749 /* ------ Any other characters are errors. ------ */
752 // This is a catch all.
753 FatalErrorIn("fluentMeshToFoam::lexer")
754 << "Do not understand characters: " << YYText() << nl
755 << " on line " << lineNo
760 /* ------ On EOF return to previous file, if none exists terminate. ------ */
767 int main(int argc, char *argv[])
769 argList::noParallel();
770 argList::validArgs.append("Fluent mesh file");
771 argList::validOptions.insert("scale", "scale factor");
772 argList::validOptions.insert("ignoreCellGroups", "cell group names");
773 argList::validOptions.insert("ignoreFaceGroups", "face group names");
774 argList::validOptions.insert("cubit", "");
776 argList args(argc, argv);
783 args.optionReadIfPresent("scale", scaleFactor);
785 HashSet<word> ignoreCellGroups;
786 if (args.optionFound("ignoreCellGroups"))
788 args.optionLookup("ignoreCellGroups")() >> ignoreCellGroups;
791 HashSet<word> ignoreFaceGroups;
792 if (args.optionFound("ignoreFaceGroups"))
794 args.optionLookup("ignoreFaceGroups")() >> ignoreFaceGroups;
797 cubitFile = args.options().found("cubit");
802 << "Assuming Cubit generated file"
803 << " (incorrect face orientation; hexadecimal zoneIDs)."
807 # include "createTime.H"
809 fileName fluentFile(args.additionalArgs()[0]);
810 IFstream fluentStream(fluentFile);
814 FatalErrorIn(args.executable())
815 << ": file " << fluentFile << " not found"
819 yyFlexLexer lexer(&fluentStream.stdStream());
821 while(lexer.yylex() != 0)
824 Info<< "\nFINISHED LEXING\n\n";
826 if (dimensionOfGrid != 3)
828 FatalErrorIn(args.executable())
829 << "Mesh is not 3D, dimension of grid: " << dimensionOfGrid
833 pointGroupZoneID.shrink();
834 pointGroupStartIndex.shrink();
835 pointGroupEndIndex.shrink();
837 faceGroupZoneID.shrink();
838 faceGroupStartIndex.shrink();
839 faceGroupEndIndex.shrink();
841 cellGroupZoneID.shrink();
842 cellGroupStartIndex.shrink();
843 cellGroupEndIndex.shrink();
844 cellGroupType.shrink();
847 // Pre-filtering: flip "owner" boundary or wrong oriented internal
848 // faces and move to neighbour
850 boolList fm(faces.size(), false);
851 forAll (faces, facei)
856 || (neighbour[facei] != -1 && owner[facei] > neighbour[facei])
862 faces[facei] = faces[facei].reverseFace();
864 Swap(owner[facei], neighbour[facei]);
869 // Foam type for Fluent type
870 // ~~~~~~~~~~~~~~~~~~~~~~~~~
872 HashTable<word> fluentToFoamType;
874 fluentToFoamType.insert("pressure", polyPatch::typeName);
875 fluentToFoamType.insert("pressure-inlet", polyPatch::typeName);
876 fluentToFoamType.insert("inlet-vent", polyPatch::typeName);
877 fluentToFoamType.insert("intake-fan", polyPatch::typeName);
878 fluentToFoamType.insert("pressure-outlet", polyPatch::typeName);
879 fluentToFoamType.insert("exhaust-fan", polyPatch::typeName);
880 fluentToFoamType.insert("outlet-vent", polyPatch::typeName);
881 fluentToFoamType.insert("pressure-far-field", polyPatch::typeName);
882 fluentToFoamType.insert("velocity-inlet", polyPatch::typeName);
883 fluentToFoamType.insert("mass-flow-inlet", polyPatch::typeName);
884 fluentToFoamType.insert("outflow", polyPatch::typeName);
886 fluentToFoamType.insert("wall" , wallPolyPatch::typeName);
888 fluentToFoamType.insert("symmetry", symmetryPolyPatch::typeName);
889 fluentToFoamType.insert("axis", symmetryPolyPatch::typeName);
891 fluentToFoamType.insert("interior", polyPatch::typeName);
892 fluentToFoamType.insert("interface", polyPatch::typeName);
893 fluentToFoamType.insert("internal", polyPatch::typeName);
894 fluentToFoamType.insert("solid", polyPatch::typeName);
895 fluentToFoamType.insert("fan", cyclicPolyPatch::typeName);
896 fluentToFoamType.insert("radiator", polyPatch::typeName);
897 fluentToFoamType.insert("porous-jump", polyPatch::typeName);
900 // Foam patch type for Fluent zone type
901 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
903 HashSet<word> fluentGroupToFoamPatch;
904 fluentGroupToFoamPatch.insert("wall");
905 fluentGroupToFoamPatch.insert("fan");
908 // Create intial empty polyMesh
909 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
915 polyMesh::defaultRegion,
919 xferCopy(pointField()),
920 xferCopy(faceList()),
921 xferCopy(labelList()),
922 xferCopy(labelList())
926 // Check the cell groups for zones ignoring those in ignoreCellGroups
927 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
928 label nCellZones = 0;
929 labelList cellZoneIDs(cellGroupZoneID.size());
931 forAll(cellGroupZoneID, cgi)
933 if (!ignoreCellGroups.found(groupName[cellGroupZoneID[cgi] ]))
935 cellZoneIDs[nCellZones++] = cgi;
939 cellZoneIDs.setSize(nCellZones);
942 // Check the face groups for boundary patches, baffles and faceZones
943 // ignoring the interior zones in ignoreCellGroups
944 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
945 DynamicList<label> patchIDs(faceGroupZoneID.size());
946 DynamicList<label> faceZoneIDs(faceGroupZoneID.size());
948 forAll(faceGroupZoneID, fgi)
950 label zoneID = faceGroupZoneID[fgi];
951 label start = faceGroupStartIndex[fgi];
953 if (groupType.found(zoneID))
955 const word& type = groupType[zoneID];
957 // Check the first element of neighbour for boundary group
958 if (neighbour[start] == -1 || fluentGroupToFoamPatch.found(type))
960 patchIDs.append(fgi);
964 if (!ignoreFaceGroups.found(groupName[faceGroupZoneID[fgi] ]))
966 faceZoneIDs.append(fgi);
970 else if (hangingNodes)
972 label end = faceGroupEndIndex[fgi];
974 Info<< "Unknown FaceGroup " << zoneID
975 << " assumed to be parent faces of refinement "
976 "patterns and ignored."
979 // Set the owner of these faces to -1 so that they do not get
981 for(label facei = start; facei <= end; facei++)
988 if (neighbour[start] == -1)
990 // Boundary face in unknown group. Create a patch for it.
991 groupType.insert(zoneID, "unknown");
992 groupName.insert(zoneID, "FaceGroup" + Foam::name(zoneID));
993 patchIDs.append(fgi);
994 Info<< "Created patch " << fgi << " for unknown FaceGroup "
995 << zoneID << '.' << endl;
999 WarningIn(args.executable())
1000 << "Unknown FaceGroup " << zoneID << " not in a zone"
1007 faceZoneIDs.shrink();
1010 // Add empty patches
1011 // ~~~~~~~~~~~~~~~~~
1013 List<polyPatch*> newPatches(patchIDs.size());
1014 HashSet<word> patchNames;
1016 wordIOList zoneToPatchName
1027 wordList(max(faceGroupZoneID) + 1, "unknown")
1030 forAll(patchIDs, patchi)
1032 label zoneID = faceGroupZoneID[patchIDs[patchi] ];
1033 word name = groupName[zoneID];
1034 const word& type = groupType[zoneID];
1036 Info<< "Creating patch " << patchi
1037 << " for zone: " << zoneID
1038 << " name: " << name
1039 << " type: " << type
1042 zoneToPatchName[zoneID] = name;
1044 uniquify(name, patchNames);
1046 HashTable<word>::const_iterator iter = fluentToFoamType.find(type);
1048 if (iter != fluentToFoamType.end())
1050 newPatches[patchi] = polyPatch::New
1062 Info<< "Adding polyPatch for unknown Fluent type " << type
1065 newPatches[patchi] = new polyPatch
1075 mesh.addPatches(newPatches);
1082 mesh.cellZones().setSize(cellZoneIDs.size());
1083 HashSet<word> cellZoneNames;
1085 forAll(cellZoneIDs, cellZonei)
1087 label zoneID = cellGroupZoneID[cellZoneIDs[cellZonei] ];
1088 word name = groupName[zoneID];
1089 const word& type = groupType[zoneID];
1091 Info<< "Creating cellZone " << cellZonei
1092 << " name: " << name
1093 << " type: " << type
1096 uniquify(name, cellZoneNames);
1098 mesh.cellZones().set
1112 mesh.faceZones().setSize(faceZoneIDs.size());
1113 HashSet<word> faceZoneNames;
1115 forAll(faceZoneIDs, faceZonei)
1117 label zoneID = faceGroupZoneID[faceZoneIDs[faceZonei] ];
1118 word name = groupName[zoneID];
1119 const word& type = groupType[zoneID];
1121 Info<< "Creating faceZone " << faceZonei
1122 << " name: " << name
1123 << " type: " << type
1126 uniquify(name, faceZoneNames);
1128 mesh.faceZones().set
1143 // Modify mesh for points/cells/faces
1144 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1146 // Mesh-change container
1147 directTopoChange meshMod(mesh, false);
1150 forAll(points, pointi)
1152 meshMod.addPoint(points[pointi], pointi, -1, true);
1157 for (label celli = 0; celli < nCells; celli++)
1161 -1, // masterPointID
1164 celli, // masterCellID
1169 // Modify cells to be in zones as required
1170 forAll(cellZoneIDs, cellZonei)
1172 label cgi = cellZoneIDs[cellZonei];
1176 label celli = cellGroupStartIndex[cgi];
1177 celli <= cellGroupEndIndex[cgi];
1181 meshMod.modifyCell(celli, cellZonei);
1186 bool doneWarning = false;
1188 // Add faceZone faces
1189 forAll(faceZoneIDs, faceZonei)
1191 label fgi = faceZoneIDs[faceZonei];
1192 label start = faceGroupStartIndex[fgi];
1193 label end = faceGroupEndIndex[fgi];
1194 label zoneID = faceGroupZoneID[fgi];
1196 Info<< "faceZone from Fluent indices: " << start
1198 << " type: " << groupType[zoneID]
1201 for (label facei = start; facei <= end; facei++)
1203 if (owner[facei] >= nCells || neighbour[facei] >= nCells)
1207 WarningIn(args.executable())
1208 << "Ignoring internal face " << facei
1209 << " on FaceZone " << zoneID
1210 << " since owner " << owner[facei] << " or neighbour "
1211 << neighbour[facei] << " outside range of cells 0.."
1213 << " Suppressing future warnings." << endl;
1224 -1, // masterPointID
1226 facei, // masterFace
1227 false, // flipFaceFlux
1229 faceZonei, // zoneID
1234 // Mark face as being done
1240 forAll(patchIDs, patchi)
1242 label fgi = patchIDs[patchi];
1243 label start = faceGroupStartIndex[fgi];
1244 label end = faceGroupEndIndex[fgi];
1245 label zoneID = faceGroupZoneID[fgi];
1247 Info<< "patch " << patchi << " from Fluent indices: " << start
1249 << " type: " << groupType[zoneID]
1252 for (label facei = start; facei <= end; facei++)
1254 if (owner[facei] >= nCells || neighbour[facei] >= nCells)
1258 WarningIn(args.executable())
1259 << "Ignoring patch face " << facei
1260 << " on FaceZone " << zoneID
1261 << " since owner " << owner[facei] << " or neighbour "
1262 << neighbour[facei] << " outside range of cells 0.."
1264 << " Suppressing future warnings." << endl;
1275 -1, // masterPointID
1277 facei, // masterFace
1278 false, // flipFaceFlux
1284 // For baffles create the opposite face
1285 if (neighbour[start] != -1)
1289 faces[facei].reverseFace(),
1292 -1, // masterPointID
1294 facei, // masterFace
1295 false, // flipFaceFlux
1302 // Mark face as being done
1307 // Add remaining internal faces
1308 forAll(owner, facei)
1310 if (owner[facei] != -1)
1312 // Check the face being added as an internal face actually is one
1313 if (neighbour[facei] == -1)
1315 FatalErrorIn(args.executable())
1316 << "Attempt of add internal face " << facei
1317 << " which is a boundary face"
1318 << exit(FatalError);
1321 if (owner[facei] >= nCells || neighbour[facei] >= nCells)
1325 WarningIn(args.executable())
1326 << "Ignoring internal face " << facei
1327 << " since owner " << owner[facei] << " or neighbour "
1328 << neighbour[facei] << " outside range of cells 0.."
1330 << " Suppressing future warnings." << endl;
1344 false, //flipFaceFlux
1356 neighbour.setSize(0);
1362 autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
1364 // Zip-up the mesh if it contained hanging nodes
1367 Info<< "Zipping mesh to remove hanging nodes" << endl;
1368 polyMeshZipUpCells(mesh);
1371 mesh.setInstance(runTime.constant());
1373 // Set the precision of the points data to 10
1374 IOstream::defaultPrecision(10);
1376 Info<< nl << "Writing mesh to " << mesh.objectPath() << endl;
1378 zoneToPatchName.write();
1381 Info<< nl << "End" << endl;
1386 /* ------------------------------------------------------------------------ *\
1387 ------ End of fluentMeshToFoam.L
1388 \* ------------------------------------------------------------------------ */