FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

ideasUnvToFoam.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2011 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Application
00025     ideasUnvToFoam
00026 
00027 Description
00028     I-Deas unv format mesh conversion.
00029 
00030     Uses either
00031     - DOF sets (757) or
00032     - face groups (2452(Cubit), 2467)
00033     to do patching.
00034     Works without but then puts all faces in defaultFaces patch.
00035 
00036 Usage
00037 
00038     - ideasUnvToFoam [OPTIONS] <.unv file>
00039 
00040     @param <.unv file> \n
00041     @todo Detailed description of argument.
00042 
00043     @param -case <dir>\n
00044     Case directory.
00045 
00046     @param -help \n
00047     Display help message.
00048 
00049     @param -doc \n
00050     Display Doxygen API documentation page for this application.
00051 
00052     @param -srcDoc \n
00053     Display Doxygen source documentation page for this application.
00054 
00055 \*---------------------------------------------------------------------------*/
00056 
00057 #include <OpenFOAM/argList.H>
00058 #include <OpenFOAM/polyMesh.H>
00059 #include <OpenFOAM/Time.H>
00060 #include <OpenFOAM/IFstream.H>
00061 #include <OpenFOAM/cellModeller.H>
00062 #include <meshTools/cellSet.H>
00063 #include <meshTools/faceSet.H>
00064 #include <OpenFOAM/DynamicList.H>
00065 #include <triSurface/triSurface.H>
00066 #include <OpenFOAM/SortableList.H>
00067 
00068 #include <cassert>
00069 
00070 using namespace Foam;
00071 
00072 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00073 
00074 namespace Foam
00075 {
00076     template<>
00077     inline unsigned Hash<face>::operator()(const face& t, unsigned seed) const
00078     {
00079         return Hasher(t.cdata(),t.size()*sizeof(label), seed);
00080     }
00081 
00082     template<>
00083     inline unsigned Hash<face>::operator()(const face& t) const
00084     {
00085         return Hash<face>::operator()(t, 0);
00086     }
00087 }
00088 const string SEPARATOR("    -1");
00089 
00090 bool isSeparator(const string& line)
00091 {
00092     return line.substr(0, 6) == SEPARATOR;
00093 }
00094 
00095 
00096 // Reads past -1 and reads element type
00097 label readTag(IFstream& is)
00098 {
00099     string tag;
00100     do
00101     {
00102         if (!is.good())
00103         {
00104             return -1;
00105         }
00106 
00107         string line;
00108 
00109         is.getLine(line);
00110 
00111         if (line.size() < 6)
00112         {
00113             return -1;
00114         }
00115 
00116         tag = line.substr(0, 6);
00117 
00118     } while (tag == SEPARATOR);
00119 
00120     return readLabel(IStringStream(tag)());
00121 }
00122 
00123 
00124 // Reads and prints header
00125 void readHeader(IFstream& is)
00126 {
00127     string line;
00128 
00129     while (is.good())
00130     {
00131         is.getLine(line);
00132 
00133         if (isSeparator(line))
00134         {
00135             break;
00136         }
00137         else
00138         {
00139             Sout<< line << endl;
00140         }
00141     }
00142 }
00143 
00144 
00145 // Skip
00146 void skipSection(IFstream& is)
00147 {
00148     Sout<< "Skipping section at line " << is.lineNumber() << '.' << endl;
00149 
00150     string line;
00151 
00152     while (is.good())
00153     {
00154         is.getLine(line);
00155 
00156         if (isSeparator(line))
00157         {
00158             break;
00159         }
00160     }
00161 }
00162 
00163 
00164 scalar readUnvScalar(const string& unvString)
00165 {
00166     string s(unvString);
00167 
00168     s.replaceAll("d", "E");
00169     s.replaceAll("D", "E");
00170 
00171     return readScalar(IStringStream(s)());
00172 }
00173 
00174 
00175 // Reads unit section
00176 void readUnits
00177 (
00178     IFstream& is,
00179     scalar& lengthScale,
00180     scalar& forceScale,
00181     scalar& tempScale,
00182     scalar& tempOffset
00183 )
00184 {
00185     Sout<< "Starting reading units at line " << is.lineNumber() << '.' << endl;
00186 
00187     string line;
00188     is.getLine(line);
00189 
00190     label l = readLabel(IStringStream(line.substr(0, 10))());
00191     Sout<< "l:" << l << endl;
00192 
00193     string units(line.substr(10, 20));
00194     Sout<< "units:" << units << endl;
00195 
00196     label unitType = readLabel(IStringStream(line.substr(30, 10))());
00197     Sout<< "unitType:" << unitType << endl;
00198 
00199     // Read lengthscales
00200     is.getLine(line);
00201 
00202     lengthScale = readUnvScalar(line.substr(0, 25));
00203     forceScale = readUnvScalar(line.substr(25, 25));
00204     tempScale = readUnvScalar(line.substr(50, 25));
00205 
00206     is.getLine(line);
00207     tempOffset = readUnvScalar(line.substr(0, 25));
00208 
00209     Sout<< "Unit factors:" << nl
00210         << "    Length scale       : " << lengthScale << nl
00211         << "    Force scale        : " << forceScale << nl
00212         << "    Temperature scale  : " << tempScale << nl
00213         << "    Temperature offset : " << tempOffset << nl
00214         << endl;
00215 }
00216 
00217 
00218 // Reads points section. Read region as well?
00219 void readPoints
00220 (
00221     IFstream& is,
00222     DynamicList<point>& points,     // coordinates
00223     DynamicList<label>& unvPointID  // unv index
00224 )
00225 {
00226     Sout<< "Starting reading points at line " << is.lineNumber() << '.' << endl;
00227 
00228     static bool hasWarned = false;
00229 
00230     while (true)
00231     {
00232         string line;
00233         is.getLine(line);
00234 
00235         label pointI = readLabel(IStringStream(line.substr(0, 10))());
00236 
00237         if (pointI == -1)
00238         {
00239             break;
00240         }
00241         else if (pointI != points.size()+1 && !hasWarned)
00242         {
00243             hasWarned = true;
00244 
00245             IOWarningIn
00246             (
00247                 "readPoints(IFstream&, label&, DynamicList<point>"
00248                 ", DynamicList<label>&)",
00249                 is
00250             )   << "Points not in order starting at point " << pointI
00251                 //<< " at line " << is.lineNumber()
00252                 //<< abort(FatalError);
00253                 << endl;
00254         }
00255 
00256         point pt;
00257         is.getLine(line);
00258         pt[0] = readUnvScalar(line.substr(0, 25));
00259         pt[1] = readUnvScalar(line.substr(25, 25));
00260         pt[2] = readUnvScalar(line.substr(50, 25));
00261 
00262         unvPointID.append(pointI);
00263         points.append(pt);
00264     }
00265 
00266     points.shrink();
00267     unvPointID.shrink();
00268 
00269     Sout<< "Read " << points.size() << " points." << endl;
00270 }
00271 
00272 void addAndExtend
00273 (
00274     DynamicList<label>& indizes,
00275     label cellI,
00276     label val
00277 )
00278 {
00279     if (indizes.size() < (cellI+1))
00280     {
00281         indizes.setSize(cellI+1,-1);
00282     }
00283     indizes[cellI] = val;
00284 }
00285 
00286 // Reads cells section. Read region as well? Not handled yet but should just
00287 // be a matter of reading corresponding to boundaryFaces the correct property
00288 // and sorting it later on.
00289 void readCells
00290 (
00291     IFstream& is,
00292     DynamicList<cellShape>& cellVerts,
00293     DynamicList<label>& cellMaterial,
00294     DynamicList<label>& boundaryFaceIndices,
00295     DynamicList<face>& boundaryFaces,
00296     DynamicList<label>& cellCorrespondence,
00297     DynamicList<label>& unvPointID  // unv index
00298 )
00299 {
00300     Sout<< "Starting reading cells at line " << is.lineNumber() << '.' << endl;
00301 
00302     // Invert point numbering.
00303     label maxUnvPoint = 0;
00304     forAll(unvPointID, pointI)
00305     {
00306         maxUnvPoint = max(maxUnvPoint, unvPointID[pointI]);
00307     }
00308     labelList unvToFoam(invert(maxUnvPoint+1, unvPointID));
00309 
00310 
00311     const cellModel& hex = *(cellModeller::lookup("hex"));
00312     const cellModel& prism = *(cellModeller::lookup("prism"));
00313     const cellModel& tet = *(cellModeller::lookup("tet"));
00314 
00315     labelHashSet skippedElements;
00316 
00317     labelHashSet foundFeType;
00318 
00319     while (true)
00320     {
00321         string line;
00322         is.getLine(line);
00323 
00324         if (isSeparator(line))
00325         {
00326             break;
00327         }
00328 
00329         IStringStream lineStr(line);
00330         label cellI, feID, physProp, matProp, colour, nNodes;
00331         lineStr >> cellI >> feID >> physProp >> matProp >> colour >> nNodes;
00332 
00333         if (foundFeType.insert(feID))
00334         {
00335             Info<< "First occurrence of element type " << feID
00336                 << " for cell " << cellI << " at line "
00337                 << is.lineNumber() << endl;
00338         }
00339 
00340         if (feID == 11)
00341         {
00342             // Rod. Skip.
00343             is.getLine(line);
00344             is.getLine(line);
00345         }
00346         else if (feID == 171)
00347         {
00348             // Rod. Skip.
00349             is.getLine(line);
00350         }
00351         else if (feID == 41 || feID == 91)
00352         {
00353             // Triangle. Save - used for patching later on.
00354             is.getLine(line);
00355 
00356             face cVerts(3);
00357             IStringStream lineStr(line);
00358             lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2];
00359             boundaryFaces.append(cVerts);
00360             boundaryFaceIndices.append(cellI);
00361         }
00362         else if (feID == 44 || feID == 94)
00363         {
00364             // Quad. Save - used for patching later on.
00365             is.getLine(line);
00366 
00367             face cVerts(4);
00368             IStringStream lineStr(line);
00369             lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
00370             boundaryFaces.append(cVerts);
00371             boundaryFaceIndices.append(cellI);
00372         }
00373         else if (feID == 111)
00374         {
00375             // Tet.
00376             is.getLine(line);
00377 
00378             labelList cVerts(4);
00379             IStringStream lineStr(line);
00380             lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
00381 
00382             cellVerts.append(cellShape(tet, cVerts, true));
00383             cellMaterial.append(physProp);
00384             addAndExtend(cellCorrespondence,cellI,cellMaterial.size()-1);
00385 
00386             if (cellVerts[cellVerts.size()-1].size() != cVerts.size())
00387             {
00388                 Pout<< "Line:" << is.lineNumber()
00389                     << " element:" << cellI
00390                     << " type:" << feID
00391                     << " collapsed from " << cVerts << nl
00392                     << " to:" << cellVerts[cellVerts.size()-1]
00393                     << endl;
00394             }
00395         }
00396         else if (feID == 112)
00397         {
00398             // Wedge.
00399             is.getLine(line);
00400 
00401             labelList cVerts(6);
00402             IStringStream lineStr(line);
00403             lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3]
00404                     >> cVerts[4] >> cVerts[5];
00405 
00406             cellVerts.append(cellShape(prism, cVerts, true));
00407             cellMaterial.append(physProp);
00408             addAndExtend(cellCorrespondence,cellI,cellMaterial.size()-1);
00409 
00410             if (cellVerts[cellVerts.size()-1].size() != cVerts.size())
00411             {
00412                 Pout<< "Line:" << is.lineNumber()
00413                     << " element:" << cellI
00414                     << " type:" << feID
00415                     << " collapsed from " << cVerts << nl
00416                     << " to:" << cellVerts[cellVerts.size()-1]
00417                     << endl;
00418             }
00419         }
00420         else if (feID == 115)
00421         {
00422             // Hex.
00423             is.getLine(line);
00424 
00425             labelList cVerts(8);
00426             IStringStream lineStr(line);
00427             lineStr
00428                 >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3]
00429                 >> cVerts[4] >> cVerts[5] >> cVerts[6] >> cVerts[7];
00430 
00431             cellVerts.append(cellShape(hex, cVerts, true));
00432             cellMaterial.append(physProp);
00433             addAndExtend(cellCorrespondence,cellI,cellMaterial.size()-1);
00434 
00435             if (cellVerts[cellVerts.size()-1].size() != cVerts.size())
00436             {
00437                 Pout<< "Line:" << is.lineNumber()
00438                     << " element:" << cellI
00439                     << " type:" << feID
00440                     << " collapsed from " << cVerts << nl
00441                     << " to:" << cellVerts[cellVerts.size()-1]
00442                     << endl;
00443             }
00444         }
00445         else if (feID == 118)
00446         {
00447             // Parabolic Tet
00448 
00449             is.getLine(line);
00450 
00451             labelList cVerts(4);
00452             label dummy;
00453             {
00454                 IStringStream lineStr(line);
00455                 lineStr
00456                     >> cVerts[0] >> dummy >> cVerts[1] >> dummy
00457                     >> cVerts[2];
00458             }
00459             is.getLine(line);
00460             {
00461                 IStringStream lineStr(line);
00462                 lineStr >> dummy>> cVerts[3];
00463             }
00464 
00465             cellVerts.append(cellShape(tet, cVerts, true));
00466             cellMaterial.append(physProp);
00467             addAndExtend(cellCorrespondence,cellI,cellMaterial.size()-1);
00468 
00469             if (cellVerts[cellVerts.size()-1].size() != cVerts.size())
00470             {
00471                 Pout<< "Line:" << is.lineNumber()
00472                     << " element:" << cellI
00473                     << " type:" << feID
00474                     << " collapsed from " << cVerts << nl
00475                     << " to:" << cellVerts[cellVerts.size()-1]
00476                     << endl;
00477             }
00478         }
00479         else
00480         {
00481             if (skippedElements.insert(feID))
00482             {
00483                 IOWarningIn("readCells(IFstream&, label&)", is)
00484                     << "Cell type " << feID << " not supported" << endl;
00485             }
00486             is.getLine(line);  //Do nothing
00487         }
00488     }
00489 
00490     cellVerts.shrink();
00491     cellMaterial.shrink();
00492     boundaryFaces.shrink();
00493     boundaryFaceIndices.shrink();
00494     cellCorrespondence.shrink();
00495 
00496     Sout<< "Read " << cellVerts.size() << " cells"
00497         << " and " << boundaryFaces.size() << " boundary faces." << endl;
00498 }
00499 
00500 
00501 void readSets
00502 (
00503     IFstream& is,
00504     DynamicList<word>& patchNames,
00505     DynamicList<labelList>& patchFaceIndices
00506 )
00507 {
00508     Sout<< "Starting reading patches at line " << is.lineNumber() << '.'
00509         << endl;
00510 
00511     while(true)
00512     {
00513         string line;
00514         is.getLine(line);
00515 
00516         if (isSeparator(line))
00517         {
00518             break;
00519         }
00520 
00521         IStringStream lineStr(line);
00522         label group, constraintSet, restraintSet, loadSet, dofSet,
00523             tempSet, contactSet, nFaces;
00524         lineStr
00525             >> group >> constraintSet >> restraintSet >> loadSet
00526             >> dofSet >> tempSet >> contactSet >> nFaces;
00527 
00528         is.getLine(line);
00529         word groupName = string::validate<word>(line);
00530 
00531         Info<< "For group " << group
00532             << " named " << groupName
00533             << " trying to read " << nFaces << " patch face indices."
00534             << endl;
00535 
00536         labelList groupIndices(nFaces);
00537         label groupType = -1;
00538         nFaces = 0;
00539 
00540         while (nFaces < groupIndices.size())
00541         {
00542             is.getLine(line);
00543             IStringStream lineStr(line);
00544 
00545             // Read one (for last face) or two entries from line.
00546             label nRead = 2;
00547             if (nFaces == groupIndices.size()-1)
00548             {
00549                 nRead = 1;
00550             }
00551 
00552             for (label i = 0; i < nRead; i++)
00553             {
00554                 label tag, nodeLeaf, component;
00555 
00556                 lineStr >> groupType >> tag >> nodeLeaf >> component;
00557 
00558                 groupIndices[nFaces++] = tag;
00559             }
00560         }
00561 
00562 
00563         // Store
00564         if (groupType == 8)
00565         {
00566             patchNames.append(groupName);
00567             patchFaceIndices.append(groupIndices);
00568         }
00569         else
00570         {
00571             IOWarningIn("readSets(..)", is)
00572                 << "When reading patches expect entity type code 8"
00573                 << nl << "    Skipping group code " << groupType
00574                 << endl;
00575         }
00576     }
00577 
00578     patchNames.shrink();
00579     patchFaceIndices.shrink();
00580 }
00581 
00582 
00583 
00584 // Read dof set (757)
00585 void readDOFS
00586 (
00587     IFstream& is,
00588     DynamicList<word>& patchNames,
00589     DynamicList<labelList>& dofVertices
00590 )
00591 {
00592     Sout<< "Starting reading constraints at line " << is.lineNumber() << '.'
00593         << endl;
00594 
00595     string line;
00596     is.getLine(line);
00597     label group;
00598     {
00599         IStringStream lineStr(line);
00600         lineStr >> group;
00601     }
00602 
00603     is.getLine(line);
00604     {
00605         IStringStream lineStr(line);
00606         patchNames.append(lineStr);
00607     }
00608 
00609     Info<< "For DOF set " << group
00610         << " named " << patchNames[patchNames.size()-1]
00611         << " trying to read vertex indices."
00612         << endl;
00613 
00614     DynamicList<label> vertices;
00615     while (true)
00616     {
00617         string line;
00618         is.getLine(line);
00619 
00620         if (isSeparator(line))
00621         {
00622             break;
00623         }
00624 
00625         IStringStream lineStr(line);
00626         label pointI;
00627         lineStr >> pointI;
00628 
00629         vertices.append(pointI);
00630     }
00631 
00632     Info<< "For DOF set " << group
00633         << " named " << patchNames[patchNames.size()-1]
00634         << " read " << vertices.size() << " vertex indices." << endl;
00635 
00636     dofVertices.append(vertices.shrink());
00637 
00638     patchNames.shrink();
00639     dofVertices.shrink();
00640 }
00641 
00642 
00643 // Returns -1 or group that all of the vertices of f are in,
00644 label findPatch(const List<labelHashSet>& dofGroups, const face& f)
00645 {
00646     forAll(dofGroups, patchI)
00647     {
00648         if (dofGroups[patchI].found(f[0]))
00649         {
00650             bool allInGroup = true;
00651 
00652             // Check rest of face
00653             for (label fp = 1; fp < f.size(); fp++)
00654             {
00655                 if (!dofGroups[patchI].found(f[fp]))
00656                 {
00657                     allInGroup = false;
00658                     break;
00659                 }
00660             }
00661 
00662             if (allInGroup)
00663             {
00664                 return patchI;
00665             }
00666         }
00667     }
00668     return -1;
00669 }
00670 
00671 // Additional output while we're unsure
00672 const bool verbose=false;
00673 
00674 // Main program:
00675 
00676 int main(int argc, char *argv[])
00677 {
00678     argList::noParallel();
00679     argList::validArgs.append(".unv file");
00680     argList::validOptions.insert("dump", "");
00681 
00682 #   include <OpenFOAM/setRootCase.H>
00683 #   include <OpenFOAM/createTime.H>
00684 
00685     fileName ideasName(args.additionalArgs()[0]);
00686 
00687     IFstream inFile(ideasName.c_str());
00688 
00689     if (!inFile.good())
00690     {
00691         FatalErrorIn(args.executable())
00692             << "Cannot open file " << ideasName
00693             << exit(FatalError);
00694     }
00695 
00696 
00697     // Unit scale factors
00698     scalar lengthScale = 1;
00699     scalar forceScale = 1;
00700     scalar tempScale = 1;
00701     scalar tempOffset = 0;
00702 
00703     // Points
00704     DynamicList<point> points;
00705     // Original unv point label
00706     DynamicList<label> unvPointID;
00707 
00708     // Cells
00709     DynamicList<cellShape> cellVerts;
00710     DynamicList<label> cellMat;
00711     DynamicList<label> cellCorrespondence;
00712 
00713     // Boundary faces
00714     DynamicList<label> boundaryFaceIndices;
00715     DynamicList<face> boundaryFaces;
00716 
00717     // Patch names and patchFace indices.
00718     DynamicList<word> patchNames;
00719     DynamicList<labelList> patchFaceIndices;
00720     DynamicList<labelList> dofVertIndices;
00721 
00722 
00723     while (inFile.good())
00724     {
00725         label tag = readTag(inFile);
00726 
00727         if (tag == -1)
00728         {
00729             break;
00730         }
00731 
00732         Sout<< "Processing tag:" << tag << endl;
00733 
00734         switch (tag)
00735         {
00736             case 151:
00737                 readHeader(inFile);
00738             break;
00739 
00740             case 164:
00741                 readUnits
00742                 (
00743                     inFile,
00744                     lengthScale,
00745                     forceScale,
00746                     tempScale,
00747                     tempOffset
00748                 );
00749             break;
00750 
00751             case 2411:
00752                 readPoints(inFile, points, unvPointID);
00753             break;
00754 
00755             case 2412:
00756                 readCells
00757                 (
00758                     inFile,
00759                     cellVerts,
00760                     cellMat,
00761                     boundaryFaceIndices,
00762                     boundaryFaces,
00763                     cellCorrespondence,
00764                     unvPointID
00765                 );
00766             break;
00767 
00768             case 2452:
00769             case 2467:
00770                 readSets
00771                 (
00772                     inFile,
00773                     patchNames,
00774                     patchFaceIndices
00775                 );
00776             break;
00777 
00778             case 757:
00779                 readDOFS
00780                 (
00781                     inFile,
00782                     patchNames,
00783                     dofVertIndices
00784                 );
00785             break;
00786 
00787             default:
00788                 Sout<< "Skipping tag " << tag << " on line "
00789                     << inFile.lineNumber() << endl;
00790                 skipSection(inFile);
00791             break;
00792         }
00793         Sout<< endl;
00794     }
00795 
00796 
00797     // Invert point numbering.
00798     label maxUnvPoint = 0;
00799     forAll(unvPointID, pointI)
00800     {
00801         maxUnvPoint = max(maxUnvPoint, unvPointID[pointI]);
00802     }
00803     labelList unvToFoam(invert(maxUnvPoint+1, unvPointID));
00804 
00805 
00806     // Renumber vertex numbers on cells
00807 
00808     forAll(cellVerts, cellI)
00809     {
00810         labelList foamVerts
00811         (
00812             renumber
00813             (
00814                 unvToFoam,
00815                 static_cast<labelList&>(cellVerts[cellI])
00816             )
00817         );
00818 
00819         if (findIndex(foamVerts, -1) != -1)
00820         {
00821             FatalErrorIn(args.executable())
00822                 << "Cell " << cellI
00823                 << " unv vertices " << cellVerts[cellI]
00824                 << " has some undefined vertices " << foamVerts
00825                 << abort(FatalError);
00826         }
00827 
00828         // Bit nasty: replace vertex list.
00829         cellVerts[cellI].transfer(foamVerts);
00830     }
00831 
00832     // Renumber vertex numbers on boundaryFaces
00833 
00834     forAll(boundaryFaces, bFaceI)
00835     {
00836         labelList foamVerts(renumber(unvToFoam, boundaryFaces[bFaceI]));
00837 
00838         if (findIndex(foamVerts, -1) != -1)
00839         {
00840             FatalErrorIn(args.executable())
00841                 << "Boundary face " << bFaceI
00842                 << " unv vertices " << boundaryFaces[bFaceI]
00843                 << " has some undefined vertices " << foamVerts
00844                 << abort(FatalError);
00845         }
00846 
00847         // Bit nasty: replace vertex list.
00848         boundaryFaces[bFaceI].transfer(foamVerts);
00849     }
00850 
00851 
00852 
00853     // Patchify = create patchFaceVerts for use in cellShape construction
00854     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00855 
00856     // Works in one of two modes. Either has read boundaryFaces which
00857     // just need to be sorted according to patch. Or has read point constraint
00858     // sets (dofVertIndices).
00859 
00860     List<faceList> patchFaceVerts;
00861 
00862     labelList nrFaceCells(boundaryFaces.size(),0);
00863     HashTable<label,label> faceToCell[2];
00864 
00865     {
00866         HashTable<label, face, Hash<face> > faceToFaceID(boundaryFaces.size());
00867         forAll(boundaryFaces,faceI)
00868         {
00869             SortableList<label> foo(boundaryFaces[faceI]);
00870             face theFace(foo);
00871             faceToFaceID.insert(theFace,faceI);
00872         }
00873 
00874         forAll(cellVerts,cellI)
00875         {
00876             faceList faces = cellVerts[cellI].faces();
00877             forAll(faces,i)
00878             {
00879                 SortableList<label> foo(faces[i]);
00880                 face theFace(foo);
00881                 if (faceToFaceID.found(theFace))
00882                 {
00883                     label faceI = faceToFaceID[theFace];
00884                     if (nrFaceCells[faceI] < 2)
00885                     {
00886                         faceToCell[nrFaceCells[faceI]].insert(faceI,cellI);
00887                     }
00888                     nrFaceCells[faceI]++;
00889                 }
00890             }
00891         }
00892 
00893         label cnt = 0;
00894         forAll(nrFaceCells, faceI)
00895         {
00896             assert(nrFaceCells[faceI] == 1 || nrFaceCells[faceI] == 2);
00897             if (nrFaceCells[faceI]>1)
00898             {
00899                 cnt++;
00900             }
00901         }
00902 
00903         if (cnt>0)
00904         {
00905             Info << "Of " << boundaryFaces.size() << " so-called"
00906                 << " boundary faces " << cnt << " belong to two cells "
00907                 << "and are therefore internal" << endl;
00908         }
00909     }
00910 
00911     HashTable<labelList,word> cellZones;
00912     HashTable<labelList,word> faceZones;
00913     List<bool> isAPatch(patchNames.size(),true);
00914 
00915     if (dofVertIndices.size())
00916     {
00917         // Use the vertex constraints to patch. Is of course bit dodgy since
00918         // face goes on patch if all its vertices are on a constraint.
00919         // Note: very inefficient since goes through all faces (including
00920         // internal ones) twice. Should do a construct without patches
00921         // and then repatchify.
00922 
00923         Info<< "Using " << dofVertIndices.size()
00924             << " DOF sets to detect boundary faces."<< endl;
00925 
00926         // Renumber vertex numbers on constraints
00927         forAll(dofVertIndices, patchI)
00928         {
00929             inplaceRenumber(unvToFoam, dofVertIndices[patchI]);
00930         }
00931 
00932 
00933         // Build labelHashSet of points per dofGroup/patch
00934         List<labelHashSet> dofGroups(dofVertIndices.size());
00935 
00936         forAll(dofVertIndices, patchI)
00937         {
00938             const labelList& foamVerts = dofVertIndices[patchI];
00939 
00940             forAll(foamVerts, i)
00941             {
00942                 dofGroups[patchI].insert(foamVerts[i]);
00943             }
00944         }
00945 
00946         List<DynamicList<face> > dynPatchFaces(dofVertIndices.size());
00947 
00948         forAll(cellVerts, cellI)
00949         {
00950             const cellShape& shape = cellVerts[cellI];
00951 
00952             const faceList shapeFaces(shape.faces());
00953 
00954             forAll(shapeFaces, i)
00955             {
00956                 label patchI = findPatch(dofGroups, shapeFaces[i]);
00957 
00958                 if (patchI != -1)
00959                 {
00960                     dynPatchFaces[patchI].append(shapeFaces[i]);
00961                 }
00962             }
00963         }
00964 
00965         // Transfer
00966         patchFaceVerts.setSize(dynPatchFaces.size());
00967 
00968         forAll(dynPatchFaces, patchI)
00969         {
00970             patchFaceVerts[patchI].transfer(dynPatchFaces[patchI]);
00971         }
00972     }
00973     else
00974     {
00975         // Use the boundary faces.
00976 
00977         // Construct the patch faces by sorting the boundaryFaces according to
00978         // patch.
00979         patchFaceVerts.setSize(patchFaceIndices.size());
00980 
00981         Info<< "Sorting boundary faces according to group (patch)" << endl;
00982 
00983         // make sure that no face is used twice on the boundary
00984         // (possible for boundary-only faceZones)
00985         labelHashSet alreadyOnBoundary;
00986 
00987         // Construct map from boundaryFaceIndices
00988         Map<label> boundaryFaceToIndex(boundaryFaceIndices.size());
00989 
00990         forAll(boundaryFaceIndices, i)
00991         {
00992             boundaryFaceToIndex.insert(boundaryFaceIndices[i], i);
00993         }
00994 
00995         forAll(patchFaceVerts, patchI)
00996         {
00997             Info << patchI << ": " << patchNames[patchI] << " is " << flush;
00998 
00999             faceList& patchFaces = patchFaceVerts[patchI];
01000             const labelList& faceIndices = patchFaceIndices[patchI];
01001 
01002             patchFaces.setSize(faceIndices.size());
01003 
01004             bool duplicateFaces = false;
01005 
01006             label cnt = 0;
01007             forAll(patchFaces, i)
01008             {
01009                 if (boundaryFaceToIndex.found(faceIndices[i]))
01010                 {
01011                     label bFaceI = boundaryFaceToIndex[faceIndices[i]];
01012                     if (nrFaceCells[bFaceI] == 1)
01013                     {
01014                         patchFaces[cnt] = boundaryFaces[bFaceI];
01015                         cnt++;
01016                         if (alreadyOnBoundary.found(bFaceI))
01017                         {
01018                             duplicateFaces = true;
01019                         }
01020                     }
01021                 }
01022             }
01023 
01024             if (cnt!=patchFaces.size() || duplicateFaces)
01025             {
01026                 isAPatch[patchI] = false;
01027 
01028                 if (verbose)
01029                 {
01030                     if (cnt != patchFaces.size())
01031                     {
01032                         WarningIn(args.executable())
01033                             << "For patch " << patchI << " there were "
01034                             << patchFaces.size()-cnt
01035                             << " faces not used because they seem"
01036                             << " to be internal. "
01037                             << "This seems to be a face or a cell-zone"
01038                             << endl;
01039                     }
01040                     else
01041                     {
01042                         WarningIn(args.executable())
01043                             << "Patch "
01044                             << patchI << " has faces that are already "
01045                             << " in use on other boundary-patches,"
01046                             << " Assuming faceZoneset." << endl;
01047                     }
01048                 }
01049 
01050                 patchFaces.setSize(0); // Assume that this is no patch at all
01051 
01052                 if (cellCorrespondence[faceIndices[0]] >= 0)
01053                 {
01054                     Info << "cellZone" << endl;
01055                     labelList theCells(faceIndices.size());
01056                     forAll(faceIndices, i)
01057                     {
01058                         if (cellCorrespondence[faceIndices[0]] < 0)
01059                         {
01060                             FatalErrorIn(args.executable())
01061                                 << "The face index " << faceIndices[i]
01062                                 << " was not found amongst the cells."
01063                                 << " This kills the theory that "
01064                                 << patchNames[patchI] << " is a cell zone"
01065                                 << endl
01066                                 << abort(FatalError);
01067                         }
01068                         theCells[i] = cellCorrespondence[faceIndices[i]];
01069                     }
01070                     cellZones.insert(patchNames[patchI], theCells);
01071                 }
01072                 else
01073                 {
01074                     Info << "faceZone" << endl;
01075                     labelList theFaces(faceIndices.size());
01076                     forAll(faceIndices, i)
01077                     {
01078                         theFaces[i] = boundaryFaceToIndex[faceIndices[i]];
01079                     }
01080                     faceZones.insert(patchNames[patchI],theFaces);
01081                 }
01082             }
01083             else
01084             {
01085                 Info << "patch" << endl;
01086 
01087                 forAll(patchFaces, i)
01088                 {
01089                     label bFaceI = boundaryFaceToIndex[faceIndices[i]];
01090                     alreadyOnBoundary.insert(bFaceI);
01091                 }
01092             }
01093         }
01094     }
01095 
01096     pointField polyPoints;
01097     polyPoints.transfer(points);
01098 
01099     // Length scaling factor
01100     polyPoints /= lengthScale;
01101 
01102 
01103     // For debugging: dump boundary faces as triSurface
01104     if (args.optionFound("dump"))
01105     {
01106         DynamicList<labelledTri> triangles(boundaryFaces.size());
01107 
01108         forAll(boundaryFaces, i)
01109         {
01110             const face& f = boundaryFaces[i];
01111 
01112             faceList triFaces(f.nTriangles(polyPoints));
01113             label nTri = 0;
01114             f.triangles(polyPoints, nTri, triFaces);
01115 
01116             forAll(triFaces, triFaceI)
01117             {
01118                 const face& f = triFaces[triFaceI];
01119                 triangles.append(labelledTri(f[0], f[1], f[2], 0));
01120             }
01121         }
01122 
01123         // Create globally numbered tri surface
01124         triSurface rawSurface(triangles.shrink(), polyPoints);
01125 
01126         // Create locally numbered tri surface
01127         triSurface surface
01128         (
01129             rawSurface.localFaces(),
01130             rawSurface.localPoints()
01131         );
01132 
01133         Info<< "Writing boundary faces to STL file boundaryFaces.stl"
01134             << nl << endl;
01135 
01136         surface.write(runTime.path()/"boundaryFaces.stl");
01137     }
01138 
01139 
01140     Info<< "\nConstructing mesh with non-default patches of size:" << nl;
01141     DynamicList<word> usedPatchNames;
01142     DynamicList<faceList> usedPatchFaceVerts;
01143 
01144     forAll(patchNames, patchI)
01145     {
01146         if (isAPatch[patchI]) {
01147             Info<< "    " << patchNames[patchI] << '\t'
01148                 << patchFaceVerts[patchI].size() << nl;
01149             usedPatchNames.append(patchNames[patchI]);
01150             usedPatchFaceVerts.append(patchFaceVerts[patchI]);
01151         }
01152     }
01153     usedPatchNames.shrink();
01154     usedPatchFaceVerts.shrink();
01155 
01156     Info<< endl;
01157 
01158 
01159 
01160     // Construct mesh
01161     polyMesh mesh
01162     (
01163         IOobject
01164         (
01165             polyMesh::defaultRegion,
01166             runTime.constant(),
01167             runTime
01168         ),
01169         xferMove(polyPoints),
01170         cellVerts,
01171         usedPatchFaceVerts,             // boundaryFaces,
01172         usedPatchNames,                 // boundaryPatchNames,
01173         wordList(patchNames.size(), polyPatch::typeName), // boundaryPatchTypes,
01174         "defaultFaces",             // defaultFacesName
01175         polyPatch::typeName,        // defaultFacesType,
01176         wordList(0)                 // boundaryPatchPhysicalTypes
01177     );
01178 
01179 
01180     if (faceZones.size()>0 || cellZones.size()>0)
01181     {
01182         Info << "Adding cell and face zones" << endl;
01183 
01184         List<pointZone*> pZones(0);
01185         List<faceZone*> fZones(faceZones.size());
01186         List<cellZone*> cZones(cellZones.size());
01187 
01188         if (cellZones.size()>0)
01189         {
01190             forAll(cellZones.toc(),cnt)
01191             {
01192                 word name = cellZones.toc()[cnt];
01193                 Info<< " Cell Zone " << name << " " << tab
01194                     << cellZones[name].size() << endl;
01195 
01196                 cZones[cnt] = new cellZone
01197                 (
01198                     name,
01199                     cellZones[name],
01200                     cnt,
01201                     mesh.cellZones()
01202                 );
01203             }
01204         }
01205         if (faceZones.size() > 0)
01206         {
01207             const labelList& own = mesh.faceOwner();
01208             const labelList& nei = mesh.faceNeighbour();
01209             const pointField& centers = mesh.faceCentres();
01210             const pointField& points = mesh.points();
01211 
01212             forAll(faceZones.toc(), cnt)
01213             {
01214                 word name = faceZones.toc()[cnt];
01215                 const labelList& oldIndizes = faceZones[name];
01216                 labelList indizes(oldIndizes.size());
01217 
01218                 Info<< " Face Zone " << name << " " << tab
01219                     << oldIndizes.size() << endl;
01220 
01221                 forAll(indizes, i)
01222                 {
01223                     const label old = oldIndizes[i];
01224                     label noveau = -1;
01225                     label c1 = -1, c2 = -1;
01226                     if (faceToCell[0].found(old))
01227                     {
01228                         c1 = faceToCell[0][old];
01229                     }
01230                     if (faceToCell[1].found(old))
01231                     {
01232                         c2 = faceToCell[1][old];
01233                     }
01234                     if (c1<c2)
01235                     {
01236                         label tmp = c1;
01237                         c1 = c2;
01238                         c2 = tmp;
01239                     }
01240                     if (c2 == -1)
01241                     {
01242                         // Boundary face is part of the faceZone
01243                         forAll(own, j)
01244                         {
01245                             if (own[j] == c1)
01246                             {
01247                                 const face& f = boundaryFaces[old];
01248                                 if (mag(centers[j]-f.centre(points))<SMALL)
01249                                 {
01250                                     noveau = j;
01251                                     break;
01252                                 }
01253                             }
01254                         }
01255                     }
01256                     else
01257                     {
01258                         forAll(nei, j)
01259                         {
01260                             if
01261                             (
01262                                 (c1 == own[j] && c2 == nei[j])
01263                              || (c2 == own[j] && c1 == nei[j])
01264                             )
01265                             {
01266                                 noveau = j;
01267                                 break;
01268                             }
01269                         }
01270                     }
01271                     assert(noveau>-1);
01272                     indizes[i] = noveau;
01273                 }
01274                 fZones[cnt] = new faceZone
01275                 (
01276                     faceZones.toc()[cnt],
01277                     indizes,
01278                     boolList(indizes.size(),false),
01279                     cnt,
01280                     mesh.faceZones()
01281                 );
01282             }
01283         }
01284         mesh.addZones(pZones, fZones, cZones);
01285 
01286         Info << endl;
01287     }
01288 
01289     mesh.write();
01290 
01291     Info<< "End\n" << endl;
01292 
01293     return 0;
01294 }
01295 
01296 
01297 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines