1 /*--------------------------------*- C++ -*----------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
28 Converts a Fluent mesh to OpenFOAM format.
30 \*---------------------------------------------------------------------------*/
35 /* ------------------------------------------------------------------------ *\
36 ------ local definitions
37 \* ------------------------------------------------------------------------ */
39 #include "cyclicPolyPatch.H"
43 #include "polyTopoChange.H"
44 #include "polyMeshZipUpCells.H"
45 #include "wallPolyPatch.H"
46 #include "symmetryPolyPatch.H"
47 #include "oldCyclicPolyPatch.H"
50 #include "readHexLabel.H"
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
56 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
61 // Scale factor used to scale points (optional command line argument)
62 scalar scaleFactor = 1.0;
64 label dimensionOfGrid = 0;
69 bool hangingNodes = false;
74 labelList neighbour(0);
76 // Group type and name
77 Map<word> groupType(100);
78 Map<word> groupName(100);
81 DynamicList<label> pointGroupZoneID;
82 DynamicList<label> pointGroupStartIndex;
83 DynamicList<label> pointGroupEndIndex;
86 DynamicList<label> faceGroupZoneID;
87 DynamicList<label> faceGroupStartIndex;
88 DynamicList<label> faceGroupEndIndex;
91 DynamicList<label> cellGroupZoneID;
92 DynamicList<label> cellGroupStartIndex;
93 DynamicList<label> cellGroupEndIndex;
94 DynamicList<label> cellGroupType;
96 // Special parsing of (incorrect) Cubit files
97 bool cubitFile = false;
100 void uniquify(word& name, HashSet<word>& patchNames)
102 if (!patchNames.found(name))
104 patchNames.insert(name);
108 Info<< " name " << name << " already used";
111 word baseName = name;
115 name = baseName + "_" + Foam::name(i++);
116 } while (patchNames.found(name));
118 Info<< ", changing to " << name << endl;
123 // Dummy yywrap to keep yylex happy at compile time.
124 // It is called by yylex but is not used as the mechanism to change file.
126 #if YY_FLEX_SUBMINOR_VERSION < 34
127 extern "C" int yywrap()
129 int yyFlexLexer::yywrap()
139 some_space {one_space}+
146 hexDigit [[:xdigit:]]
154 schemeSpecialInitial [!$%&*/\\:<=>?~_^#.@']
155 schemeSpecialSubsequent [.+-]
156 schemeSymbol (({some_space}|{alpha}|{quote}|{schemeSpecialInitial})({alpha}|{quote}|{digit}|{schemeSpecialInitial}|{schemeSpecialSubsequent})*)
159 identifier {alpha}({alpha}|{digit})*
161 label [1-9]{decDigit}*
164 signedInteger [-+]?{integer}
165 word ({alpha}|{digit}|{dotColonDash})*
167 exponent_part [eE][-+]?{digit}+
168 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+".")|({digit}))
170 double ((({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))|0)
176 labelListElement {space}{zeroLabel}
177 hexLabelListElement {space}{hexLabel}
178 scalarListElement {space}{double}
179 schemeSymbolListElement {space}{schemeSymbol}
180 labelList ({labelListElement}+{space})
181 hexLabelList ({hexLabelListElement}+{space})
182 scalarList ({scalarListElement}+{space})
183 schemeSymbolList ({schemeSymbolListElement}+{space})
186 text ({space}({word}*{space})*)
187 anythingInBlock ([^)]*)
189 dateDDMMYYYY ({digit}{digit}"/"{digit}{digit}"/"{digit}{digit}{digit}{digit})
190 dateDDMonYYYY ((({digit}{digit}{space})|({digit}{space})){alpha}*{space}{digit}{digit}{digit}{digit})
191 time ({digit}{digit}":"{digit}{digit}":"{digit}{digit})
193 versionNumber ({digit}|".")*
195 header {space}"(1"{space}
196 dimension {space}"(2"{space}
197 points {space}"(10"{space}
198 faces {space}"(13"{space}
199 cells {space}"(12"{space}
200 zoneVariant1 {space}"(39"{space}
201 zoneVariant2 {space}"(45"{space}
202 faceTree {space}"(59"{space}
205 unknownPeriodicFace "17"{space}
206 periodicFace "18"{space}
208 faceParents "61"{space}
209 ignoreBlocks ("4"|"37"|"38"|"40"|"41"|"60"|"64"){space}
211 redundantBlock {space}({comment}|{unknownPeriodicFace}|{periodicFace}|{cellTree}|{faceParents}|{ignoreBlocks}){space}
213 endOfSection {space}")"{space}
217 /* ------------------------------------------------------------------------ *\
218 ----- Exclusive start states -----
219 \* ------------------------------------------------------------------------ */
227 %x readNumberOfPoints
228 %x readPointGroupData
251 %x ignoreEmbeddedBlock
255 // End of read character pointer returned by strtol and strtod
259 label pointGroupNumberOfComponents = 3;
260 label pointi = 0; // index used for reading points
261 label cmpt = 0; // component index used for reading points
264 label faceGroupElementType = -1;
265 label facei = 0; // index used for reading faces
269 /* ------------------------------------------------------------------------ *\
270 ------ Start Lexing ------
271 \* ------------------------------------------------------------------------ */
273 /* ------ Reading control header ------ */
279 <readHeader>{anythingInBlock} {
280 Info<< "Header: " << YYText() << endl;
285 BEGIN(readDimension);
288 <readDimension>{space}{label}{space} {
289 dimensionOfGrid = atoi(YYText());
290 Info<< "Dimension of grid: " << dimensionOfGrid << endl;
295 BEGIN(readPointHeader);
298 <readPointHeader>{space}{lbrac}{space}"0"{space}"1"{space} {
299 BEGIN(readNumberOfPoints);
302 <readNumberOfPoints>{hexLabel}{space}{labelList} {
303 nPoints = strtol(YYText(), &endPtr, 16);
304 Info<< "Number of points: " << nPoints << endl;
305 points.setSize(nPoints);
307 // Ignore rest of stream
310 <readPointHeader>{space}{lbrac} {
311 BEGIN(readPointGroupData);
314 <readPointGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{labelList} {
315 // Read point zone-ID, start and end-label
316 // the indices will be used for checking later.
317 pointGroupZoneID.append(strtol(YYText(), &endPtr, 16));
319 // In FOAM, indices start from zero - adjust
320 pointGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
322 pointGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
324 // point group type skipped
325 (void)strtol(endPtr, &endPtr, 16);
327 pointi = pointGroupStartIndex.last();
329 // reset number of components to default
330 pointGroupNumberOfComponents = 3;
332 // read number of components in the vector
333 if (endPtr < &(YYText()[YYLeng()-1]))
335 pointGroupNumberOfComponents = strtol(endPtr, &endPtr, 16);
338 Info<< "PointGroup: "
339 << pointGroupZoneID.last()
341 << pointGroupStartIndex.last()
343 << pointGroupEndIndex.last() << flush;
346 <readNumberOfPoints,readPointGroupData>{endOfSection} {
347 BEGIN(readPointData);
350 <readPointData>{space}{lbrac}{space} {
351 Info<< ". Reading points..." << flush;
353 yy_push_state(readScalarList);
356 <readScalarList>{signedInteger}{space} {
357 points[pointi][cmpt++] = scaleFactor*atol(YYText());
359 if (cmpt == pointGroupNumberOfComponents)
361 if (pointGroupNumberOfComponents == 2)
363 points[pointi].z() = 0.0;
371 <readScalarList>{scalar}{space} {
372 points[pointi][cmpt++] = scaleFactor*atof(YYText());
374 if (cmpt == pointGroupNumberOfComponents)
376 if (pointGroupNumberOfComponents == 2)
378 points[pointi].z() = 0.0;
386 <readScalarList>{endOfSection} {
387 Info<< "done." << endl;
389 // check read of points
390 if (pointi != pointGroupEndIndex.last()+1)
393 << "Problem with reading points: " << nl
395 << pointGroupStartIndex.last()
397 << pointGroupEndIndex.last()
398 << " last points read: " << pointi << nl
399 << " on line " << lineNo << endl;
406 BEGIN(readFaceHeader);
409 <readFaceHeader>{space}{lbrac}{space}"0"{space}"1"{space} {
410 BEGIN(readNumberOfFaces);
413 <readNumberOfFaces>{space}{hexLabel}{space}{labelListElement}+ {
414 nFaces = strtol(YYText(), &endPtr, 16);
416 Info<< "Number of faces: " << nFaces << endl;
418 faces.setSize(nFaces);
419 owner.setSize(nFaces);
420 neighbour.setSize(nFaces);
422 // Type and element type not read
425 <readFaceHeader>{space}{lbrac} {
426 BEGIN(readFaceGroupData);
429 <readFaceGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{hexLabelListElement}+ {
430 // read fluentFace zone-ID, start and end-label
431 faceGroupZoneID.append(strtol(YYText(), &endPtr, 16));
433 // In FOAM, indices start from zero - adjust
434 faceGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
436 faceGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
439 (void)strtol(endPtr, &endPtr, 16);
441 faceGroupElementType = strtol(endPtr, &endPtr, 16);
443 facei = faceGroupStartIndex.last();
446 << faceGroupZoneID.last()
448 << faceGroupStartIndex.last()
450 << faceGroupEndIndex.last() << flush;
453 <readNumberOfFaces,readFaceGroupData>{space}{endOfSection} {
457 <readFaceData>{space}{lbrac} {
458 if (faceGroupElementType == 0 || faceGroupElementType > 4)
460 Info<< ". Reading mixed faces..." << flush;
461 yy_push_state(readFacesMixed);
465 Info<< ". Reading uniform faces..." << flush;
466 yy_push_state(readFacesUniform);
470 <readFacesMixed>{space}{hexLabelList} {
471 face& curFaceLabels = faces[facei];
473 // set size of label list
474 curFaceLabels.setSize(strtol(YYText(), &endPtr, 16));
476 forAll(curFaceLabels, i)
478 curFaceLabels[i] = strtol(endPtr, &endPtr, 16) - 1;
481 // read neighbour and owner. Neighbour comes first
482 neighbour[facei] = strtol(endPtr, &endPtr, 16) - 1;
483 owner[facei] = strtol(endPtr, &endPtr, 16) - 1;
487 <readFacesUniform>{space}{hexLabelList} {
488 face& curFaceLabels = faces[facei];
490 // Set size of label list.
491 curFaceLabels.setSize(faceGroupElementType);
493 curFaceLabels[0] = strtol(YYText(), &endPtr, 16) - 1;
495 for (int i=1; i<faceGroupElementType; i++)
497 curFaceLabels[i] = strtol(endPtr, &endPtr, 16) - 1;
500 // read neighbour and owner. Neighbour comes first
501 neighbour[facei] = strtol(endPtr, &endPtr, 16) - 1;
502 owner[facei] = strtol(endPtr, &endPtr, 16) - 1;
506 <readFacesMixed,readFacesUniform>{space}{endOfSection} {
507 Info<< "done." << endl;
509 // check read of fluentFaces
510 if (facei != faceGroupEndIndex.last()+1)
513 << "Problem with reading fluentFaces: " << nl
515 << faceGroupStartIndex.last()
517 << faceGroupEndIndex.last()
518 << " last fluentFaces read: " << facei << nl
519 << " on line " << lineNo << endl;
527 BEGIN(readCellHeader);
530 <readCellHeader>{space}{lbrac}{space}"0"{space}"1"{space} {
531 BEGIN(readNumberOfCells);
534 <readNumberOfCells>{space}{hexLabel}{space}{labelListElement}+ {
535 nCells = strtol(YYText(), &endPtr, 16);
536 Info<< "Number of cells: " << nCells << endl;
539 <readCellHeader>{space}{lbrac} {
540 BEGIN(readCellGroupData);
543 <readCellGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel} {
544 // Warning. This entry must be above the next one because of the lexing
545 // rules. It is introduced to deal with the problem of reading
546 // non-standard cell definition from Tgrid, which misses the type label.
549 << "Tgrid syntax problem: " << YYText() << nl
550 << " on line " << lineNo << endl;
552 // read cell zone-ID, start and end-label
553 cellGroupZoneID.append(strtol(YYText(), &endPtr, 16));
555 // the indices will be used for checking later.
556 cellGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
558 cellGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
560 cellGroupType.append(strtol(endPtr, &endPtr, 16));
563 << cellGroupZoneID.last()
565 << cellGroupStartIndex.last()
567 << cellGroupEndIndex.last()
569 << cellGroupType.last()
573 <readCellGroupData>{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel}{space}{hexLabel} {
574 // Warning. See above
576 // read cell zone-ID, start and end-label
577 cellGroupZoneID.append(strtol(YYText(), &endPtr, 16));
579 // the indices will be used for checking later.
580 cellGroupStartIndex.append(strtol(endPtr, &endPtr, 16) - 1);
582 cellGroupEndIndex.append(strtol(endPtr, &endPtr, 16) - 1);
584 cellGroupType.append(strtol(endPtr, &endPtr, 16));
586 // Note. Potentially skip cell set if type is zero.
587 (void)strtol(endPtr, &endPtr, 16);
590 << cellGroupZoneID.last()
592 << cellGroupStartIndex.last()
594 << cellGroupEndIndex.last()
596 << cellGroupType.last()
600 <readNumberOfCells,readCellGroupData>{endOfSection} {
604 <readCellData>{space}{lbrac} {
605 // Quickly scan to the end of the cell data block and discard
607 while ((c = yyinput()) != 0 && c != ')')
612 // There are hanging nodes in the mesh so make sure it gets zipped-up
614 yy_push_state(ignoreBlock);
618 BEGIN(readZoneHeader);
622 BEGIN(readZoneHeader);
625 <readZoneHeader>{space}{lbrac} {
626 BEGIN(readZoneGroupData);
629 <readZoneGroupData>{space}{hexLabel}{space}{word}{space}{word}{space}{label}? {
630 IStringStream zoneDataStream(YYText());
632 // cell zone-ID not in hexadecimal!!! Inconsistency
637 zoneID = readHexLabel(zoneDataStream);
641 zoneID = readLabel(zoneDataStream);
644 groupType.insert(zoneID, word(zoneDataStream));
645 groupName.insert(zoneID, word(zoneDataStream));
647 Info<< "Zone: " << zoneID
648 << " name: " << groupName[zoneID]
649 << " type: " << groupType[zoneID] << flush;
652 <readZoneGroupData>{endOfSection} {
656 <readZoneData>{space}{lbrac} {
657 Info<< ". Reading zone data..." << flush;
658 yy_push_state(readZoneBlock);
661 <readZoneBlock>{space}{schemeSymbolList} {
664 <readZoneBlock>{lbrac} {
666 // << "Found unknown block in zone: " << YYText() << nl
667 // << " on line " << lineNo << endl;
668 yy_push_state(ignoreBlock);
671 <readZoneBlock>{endOfSection} {
672 Info<< "done." << endl;
678 /* ------ Reading end of section and others ------ */
680 <readHeader,readDimension,readPointData,readFaceData,readCellData,readZoneData>{space}{endOfSection} {
684 /* ------ Reading unknown type or non-standard comment ------ */
688 << "Found unknown block of type: "
689 << Foam::string(YYText())(1, YYLeng()-1) << nl
690 << " on line " << lineNo << endl;
692 yy_push_state(ignoreBlock);
695 {lbrac}{redundantBlock} {
696 yy_push_state(ignoreBlock);
699 <ignoreBlock,ignoreEmbeddedBlock>{space}{quote}{text}{quote} {
702 <ignoreBlock,ignoreEmbeddedBlock>{space}{schemeSymbol} {
705 <ignoreBlock,ignoreEmbeddedBlock>{space}{lbrac} {
706 yy_push_state(ignoreEmbeddedBlock);
710 <ignoreBlock,ignoreEmbeddedBlock>{space}{endOfSection} {
714 <ignoreBlock,ignoreEmbeddedBlock>{space}{labelList} {
717 <ignoreBlock,ignoreEmbeddedBlock>{space}{hexLabelList} {
720 <ignoreBlock,ignoreEmbeddedBlock>{space}{scalarList} {
723 <ignoreBlock,ignoreEmbeddedBlock>{space}{schemeSymbolList} {
726 <ignoreBlock,ignoreEmbeddedBlock>{space}{text} {
730 /* ------ Count newlines. ------ */
737 /* ------ Ignore remaining space. ------ */
743 /* ------ Any other characters are errors. ------ */
746 // This is a catch all.
747 FatalErrorIn("fluentMeshToFoam::lexer")
748 << "Do not understand characters: " << YYText() << nl
749 << " on line " << lineNo
754 /* ------ On EOF return to previous file, if none exists terminate. ------ */
761 int main(int argc, char *argv[])
763 argList::noParallel();
764 argList::validArgs.append("Fluent mesh file");
769 "geometry scaling factor - default is 1"
775 "specify cell groups to ignore"
781 "specify face groups to ignore"
784 argList::addBoolOption
787 "special parsing of (incorrect) cubit files"
790 argList args(argc, argv);
797 args.optionReadIfPresent("scale", scaleFactor);
799 wordHashSet ignoreCellGroups;
800 wordHashSet ignoreFaceGroups;
802 args.optionReadIfPresent("ignoreCellGroups", ignoreCellGroups);
803 args.optionReadIfPresent("ignoreFaceGroups", ignoreFaceGroups);
805 cubitFile = args.options().found("cubit");
810 << "Assuming Cubit generated file"
811 << " (incorrect face orientation; hexadecimal zoneIDs)."
816 # include "createTime.H"
818 const fileName fluentFile = args[1];
819 IFstream fluentStream(fluentFile);
823 FatalErrorIn(args.executable())
824 << ": file " << fluentFile << " not found"
828 yyFlexLexer lexer(&fluentStream.stdStream());
830 while (lexer.yylex() != 0)
833 Info<< "\nFINISHED LEXING\n\n";
835 if (dimensionOfGrid != 3)
837 FatalErrorIn(args.executable())
838 << "Mesh is not 3D, dimension of grid: " << dimensionOfGrid
842 pointGroupZoneID.shrink();
843 pointGroupStartIndex.shrink();
844 pointGroupEndIndex.shrink();
846 faceGroupZoneID.shrink();
847 faceGroupStartIndex.shrink();
848 faceGroupEndIndex.shrink();
850 cellGroupZoneID.shrink();
851 cellGroupStartIndex.shrink();
852 cellGroupEndIndex.shrink();
853 cellGroupType.shrink();
856 // Pre-filtering: flip "owner" boundary or wrong oriented internal
857 // faces and move to neighbour
859 boolList fm(faces.size(), false);
865 || (neighbour[facei] != -1 && owner[facei] > neighbour[facei])
873 Swap(owner[facei], neighbour[facei]);
878 // Foam type for Fluent type
879 // ~~~~~~~~~~~~~~~~~~~~~~~~~
881 HashTable<word> fluentToFoamType;
883 fluentToFoamType.insert("pressure", polyPatch::typeName);
884 fluentToFoamType.insert("pressure-inlet", polyPatch::typeName);
885 fluentToFoamType.insert("inlet-vent", polyPatch::typeName);
886 fluentToFoamType.insert("intake-fan", polyPatch::typeName);
887 fluentToFoamType.insert("pressure-outlet", polyPatch::typeName);
888 fluentToFoamType.insert("exhaust-fan", polyPatch::typeName);
889 fluentToFoamType.insert("outlet-vent", polyPatch::typeName);
890 fluentToFoamType.insert("pressure-far-field", polyPatch::typeName);
891 fluentToFoamType.insert("velocity-inlet", polyPatch::typeName);
892 fluentToFoamType.insert("mass-flow-inlet", polyPatch::typeName);
893 fluentToFoamType.insert("outflow", polyPatch::typeName);
895 fluentToFoamType.insert("wall" , wallPolyPatch::typeName);
897 fluentToFoamType.insert("symmetry", symmetryPolyPatch::typeName);
898 fluentToFoamType.insert("axis", symmetryPolyPatch::typeName);
900 fluentToFoamType.insert("interior", polyPatch::typeName);
901 fluentToFoamType.insert("interface", polyPatch::typeName);
902 fluentToFoamType.insert("internal", polyPatch::typeName);
903 fluentToFoamType.insert("solid", polyPatch::typeName);
904 fluentToFoamType.insert("fan", oldCyclicPolyPatch::typeName);
905 fluentToFoamType.insert("radiator", polyPatch::typeName);
906 fluentToFoamType.insert("porous-jump", polyPatch::typeName);
908 //- Periodic halves map directly into split cyclics. The problem is the
909 // initial matching since we require knowledge of the transformation.
910 // It is ok if the periodics are already ordered. We should read the
911 // periodic shadow faces section (section 18) to give use the ordering
912 // For now just disable.
913 //fluentToFoamType.insert("periodic", cyclicPolyPatch::typeName);
916 // Foam patch type for Fluent zone type
917 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
919 HashSet<word> fluentGroupToFoamPatch;
920 fluentGroupToFoamPatch.insert("wall");
921 fluentGroupToFoamPatch.insert("fan");
924 // Create intial empty polyMesh
925 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
931 polyMesh::defaultRegion,
935 xferCopy(pointField()),
936 xferCopy(faceList()),
937 xferCopy(labelList()),
938 xferCopy(labelList())
942 // Check the cell groups for zones ignoring those in ignoreCellGroups
943 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
944 label nCellZones = 0;
945 labelList cellZoneIDs(cellGroupZoneID.size());
947 forAll(cellGroupZoneID, cgi)
949 if (!ignoreCellGroups.found(groupName[cellGroupZoneID[cgi] ]))
951 cellZoneIDs[nCellZones++] = cgi;
955 cellZoneIDs.setSize(nCellZones);
958 // Check the face groups for boundary patches, baffles and faceZones
959 // ignoring the interior zones in ignoreCellGroups
960 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
961 DynamicList<label> patchIDs(faceGroupZoneID.size());
962 DynamicList<label> faceZoneIDs(faceGroupZoneID.size());
964 forAll(faceGroupZoneID, fgi)
966 label zoneID = faceGroupZoneID[fgi];
967 label start = faceGroupStartIndex[fgi];
969 if (groupType.found(zoneID))
971 const word& type = groupType[zoneID];
973 // Check the first element of neighbour for boundary group
974 if (neighbour[start] == -1 || fluentGroupToFoamPatch.found(type))
976 patchIDs.append(fgi);
980 if (!ignoreFaceGroups.found(groupName[faceGroupZoneID[fgi] ]))
982 faceZoneIDs.append(fgi);
986 else if (hangingNodes)
988 label end = faceGroupEndIndex[fgi];
990 Info<< "Unknown FaceGroup " << zoneID
991 << " assumed to be parent faces of refinement "
992 "patterns and ignored."
995 // Set the owner of these faces to -1 so that they do not get
997 for (label facei = start; facei <= end; facei++)
1004 if (neighbour[start] == -1)
1006 // Boundary face in unknown group. Create a patch for it.
1007 groupType.insert(zoneID, "unknown");
1008 groupName.insert(zoneID, "FaceGroup" + Foam::name(zoneID));
1009 patchIDs.append(fgi);
1010 Info<< "Created patch " << fgi << " for unknown FaceGroup "
1011 << zoneID << '.' << endl;
1015 WarningIn(args.executable())
1016 << "Unknown FaceGroup " << zoneID << " not in a zone"
1023 faceZoneIDs.shrink();
1026 // Add empty patches
1027 // ~~~~~~~~~~~~~~~~~
1029 List<polyPatch*> newPatches(patchIDs.size());
1030 HashSet<word> patchNames;
1032 forAll(patchIDs, patchi)
1034 label zoneID = faceGroupZoneID[patchIDs[patchi] ];
1035 word name = groupName[zoneID];
1036 const word& type = groupType[zoneID];
1038 Info<< "Creating patch " << patchi
1039 << " for zone: " << zoneID
1040 << " name: " << name
1041 << " type: " << type
1044 uniquify(name, patchNames);
1046 HashTable<word>::const_iterator iter = fluentToFoamType.find(type);
1048 if (iter != fluentToFoamType.end())
1050 // See if we have a periodic and can derive the other side.
1051 word neighbPatchName;
1052 if (iter() == cyclicPolyPatch::typeName)
1055 size_t n = name.rfind("-SIDE-1");
1057 if (n != string::npos)
1059 neighbPatchName = name.substr(0, n) + "-SIDE-2";
1063 n = name.rfind("-SIDE-2");
1064 if (n != string::npos)
1066 neighbPatchName = name.substr(0, n) + "-SIDE-1";
1071 if (neighbPatchName.size())
1073 Info<< "Adding cyclicPolyPatch for Fluent zone " << name
1074 << " with neighbour patch " << neighbPatchName
1077 newPatches[patchi] = new cyclicPolyPatch
1083 mesh.boundaryMesh(),
1085 cyclicPolyPatch::NOORDERING,
1093 newPatches[patchi] = polyPatch::New
1106 Info<< "Adding polyPatch for unknown Fluent type " << type
1109 newPatches[patchi] = new polyPatch
1119 mesh.addPatches(newPatches);
1126 mesh.cellZones().setSize(cellZoneIDs.size());
1127 HashSet<word> cellZoneNames;
1129 forAll(cellZoneIDs, cellZonei)
1131 label zoneID = cellGroupZoneID[cellZoneIDs[cellZonei] ];
1132 word name = groupName[zoneID];
1133 const word& type = groupType[zoneID];
1135 Info<< "Creating cellZone " << cellZonei
1136 << " name: " << name
1137 << " type: " << type
1140 uniquify(name, cellZoneNames);
1142 mesh.cellZones().set
1156 mesh.faceZones().setSize(faceZoneIDs.size());
1157 HashSet<word> faceZoneNames;
1159 forAll(faceZoneIDs, faceZonei)
1161 label zoneID = faceGroupZoneID[faceZoneIDs[faceZonei] ];
1162 word name = groupName[zoneID];
1163 const word& type = groupType[zoneID];
1165 Info<< "Creating faceZone " << faceZonei
1166 << " name: " << name
1167 << " type: " << type
1170 uniquify(name, faceZoneNames);
1172 mesh.faceZones().set
1187 // Modify mesh for points/cells/faces
1188 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1190 // Mesh-change container
1191 polyTopoChange meshMod(mesh, false);
1194 forAll(points, pointi)
1196 meshMod.addPoint(points[pointi], pointi, -1, true);
1201 for (label celli = 0; celli < nCells; celli++)
1205 -1, // masterPointID
1208 celli, // masterCellID
1213 // Modify cells to be in zones as required
1214 forAll(cellZoneIDs, cellZonei)
1216 label cgi = cellZoneIDs[cellZonei];
1220 label celli = cellGroupStartIndex[cgi];
1221 celli <= cellGroupEndIndex[cgi];
1225 meshMod.modifyCell(celli, cellZonei);
1230 bool doneWarning = false;
1232 // Add faceZone faces
1233 forAll(faceZoneIDs, faceZonei)
1235 label fgi = faceZoneIDs[faceZonei];
1236 label start = faceGroupStartIndex[fgi];
1237 label end = faceGroupEndIndex[fgi];
1238 label zoneID = faceGroupZoneID[fgi];
1240 Info<< "faceZone from Fluent indices: " << start
1242 << " type: " << groupType[zoneID]
1245 for (label facei = start; facei <= end; facei++)
1247 if (owner[facei] >= nCells || neighbour[facei] >= nCells)
1251 WarningIn(args.executable())
1252 << "Ignoring internal face " << facei
1253 << " on FaceZone " << zoneID
1254 << " since owner " << owner[facei] << " or neighbour "
1255 << neighbour[facei] << " outside range of cells 0.."
1257 << " Suppressing future warnings." << endl;
1268 -1, // masterPointID
1270 facei, // masterFace
1271 false, // flipFaceFlux
1273 faceZonei, // zoneID
1274 fm[facei] // zoneFlip
1278 // Mark face as being done
1284 forAll(patchIDs, patchi)
1286 label fgi = patchIDs[patchi];
1287 label start = faceGroupStartIndex[fgi];
1288 label end = faceGroupEndIndex[fgi];
1289 label zoneID = faceGroupZoneID[fgi];
1291 Info<< "patch " << patchi << " from Fluent indices: " << start
1293 << " type: " << groupType[zoneID]
1296 for (label facei = start; facei <= end; facei++)
1298 if (owner[facei] >= nCells || neighbour[facei] >= nCells)
1302 WarningIn(args.executable())
1303 << "Ignoring patch face " << facei
1304 << " on FaceZone " << zoneID
1305 << " since owner " << owner[facei] << " or neighbour "
1306 << neighbour[facei] << " outside range of cells 0.."
1308 << " Suppressing future warnings." << endl;
1319 -1, // masterPointID
1321 facei, // masterFace
1322 false, // flipFaceFlux
1328 // For baffles create the opposite face
1329 if (neighbour[start] != -1)
1333 faces[facei].reverseFace(),
1336 -1, // masterPointID
1338 facei, // masterFace
1339 false, // flipFaceFlux
1346 // Mark face as being done
1351 // Add remaining internal faces
1352 forAll(owner, facei)
1354 if (owner[facei] != -1)
1356 // Check the face being added as an internal face actually is one
1357 if (neighbour[facei] == -1)
1359 FatalErrorIn(args.executable())
1360 << "Attempt of add internal face " << facei
1361 << " which is a boundary face"
1362 << exit(FatalError);
1365 if (owner[facei] >= nCells || neighbour[facei] >= nCells)
1369 WarningIn(args.executable())
1370 << "Ignoring internal face " << facei
1371 << " since owner " << owner[facei] << " or neighbour "
1372 << neighbour[facei] << " outside range of cells 0.."
1374 << " Suppressing future warnings." << endl;
1388 false, //flipFaceFlux
1400 neighbour.setSize(0);
1406 autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
1408 // Zip-up the mesh if it contained hanging nodes
1411 Info<< "Zipping mesh to remove hanging nodes" << endl;
1412 polyMeshZipUpCells(mesh);
1415 mesh.setInstance(runTime.constant());
1417 // Set the precision of the points data to 10
1418 IOstream::defaultPrecision(10);
1420 Info<< nl << "Writing mesh to " << mesh.objectPath() << endl;
1424 Info<< "\nEnd\n" << endl;
1429 /* ------------------------------------------------------------------------ *\
1430 ------ End of fluentMeshToFoam.L
1431 \* ------------------------------------------------------------------------ */