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

STARCDsurfaceFormat.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-2010 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 \*---------------------------------------------------------------------------*/
00025 
00026 #include "STARCDsurfaceFormat.H"
00027 #include <OpenFOAM/ListOps.H>
00028 
00029 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00030 
00031 template<class Face>
00032 inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
00033 (
00034     Ostream& os,
00035     const Face& f,
00036     const label cellId,
00037     const label cellTableId
00038 )
00039 {
00040     os  << cellId                    // includes 1 offset
00041         << ' ' << starcdShellShape_  // 3(shell) shape
00042         << ' ' << f.size()
00043         << ' ' << cellTableId
00044         << ' ' << starcdShellType_;  // 4(shell)
00045 
00046     // primitives have <= 8 vertices, but prevent overrun anyhow
00047     // indent following lines for ease of reading
00048     label count = 0;
00049     forAll(f, fp)
00050     {
00051         if ((count % 8) == 0)
00052         {
00053             os  << nl << "  " << cellId;
00054         }
00055         os  << ' ' << f[fp] + 1;
00056         count++;
00057     }
00058     os  << endl;
00059 }
00060 
00061 
00062 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00063 
00064 template<class Face>
00065 Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
00066 (
00067     const fileName& filename
00068 )
00069 {
00070     read(filename);
00071 }
00072 
00073 
00074 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00075 
00076 template<class Face>
00077 bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
00078 (
00079     const fileName& filename
00080 )
00081 {
00082     const bool mustTriangulate = this->isTri();
00083     this->clear();
00084 
00085     fileName baseName = filename.lessExt();
00086 
00087     // STAR-CD index of points
00088     List<label> pointId;
00089 
00090     // read points from .vrt file
00091     readPoints
00092     (
00093         IFstream(baseName + ".vrt")(),
00094         this->storedPoints(),
00095         pointId
00096     );
00097 
00098     // Build inverse mapping (STAR-CD pointId -> index)
00099     Map<label> mapPointId(2*pointId.size());
00100     forAll(pointId, i)
00101     {
00102         mapPointId.insert(pointId[i], i);
00103     }
00104     pointId.clear();
00105 
00106     //
00107     // read .cel file
00108     // ~~~~~~~~~~~~~~
00109     IFstream is(baseName + ".cel");
00110     if (!is.good())
00111     {
00112         FatalErrorIn
00113         (
00114             "fileFormats::STARCDsurfaceFormat::read(const fileName&)"
00115         )
00116             << "Cannot read file " << is.name()
00117             << exit(FatalError);
00118     }
00119 
00120     readHeader(is, "PROSTAR_CELL");
00121 
00122     DynamicList<Face>  dynFaces;
00123     DynamicList<label> dynZones;
00124     DynamicList<word>  dynNames;
00125     DynamicList<label> dynSizes;
00126     Map<label> lookup;
00127 
00128     // assume the cellTableIds are not intermixed
00129     bool sorted = true;
00130     label zoneI = 0;
00131 
00132     label lineLabel, shapeId, nLabels, cellTableId, typeId;
00133     DynamicList<label> vertexLabels(64);
00134 
00135     while ((is >> lineLabel).good())
00136     {
00137         is >> shapeId >> nLabels >> cellTableId >> typeId;
00138 
00139         vertexLabels.clear();
00140         vertexLabels.reserve(nLabels);
00141 
00142         // read indices - max 8 per line
00143         for (label i = 0; i < nLabels; ++i)
00144         {
00145             label vrtId;
00146             if ((i % 8) == 0)
00147             {
00148                is >> lineLabel;
00149             }
00150             is >> vrtId;
00151 
00152             // convert original vertex id to point label
00153             vertexLabels.append(mapPointId[vrtId]);
00154         }
00155 
00156         if (typeId == starcdShellType_)
00157         {
00158             // Convert groupID into zoneID
00159             Map<label>::const_iterator fnd = lookup.find(cellTableId);
00160             if (fnd != lookup.end())
00161             {
00162                 if (zoneI != fnd())
00163                 {
00164                     // cellTableIds are intermixed
00165                     sorted = false;
00166                 }
00167                 zoneI = fnd();
00168             }
00169             else
00170             {
00171                 zoneI = dynSizes.size();
00172                 lookup.insert(cellTableId, zoneI);
00173                 dynNames.append(word("cellTable_") + ::Foam::name(zoneI));
00174                 dynSizes.append(0);
00175             }
00176 
00177             SubList<label> vertices(vertexLabels, vertexLabels.size());
00178             if (mustTriangulate && nLabels > 3)
00179             {
00180                 face f(vertices);
00181 
00182                 faceList triFaces(f.nTriangles());
00183                 label nTri = 0;
00184                 f.triangles(this->points(), nTri, triFaces);
00185 
00186                 forAll(triFaces, faceI)
00187                 {
00188                     // a triangular face, but not yet a triFace
00189                     dynFaces.append
00190                     (
00191                         triFace
00192                         (
00193                             static_cast<UList<label>&>(triFaces[faceI])
00194                         )
00195                     );
00196                     dynZones.append(zoneI);
00197                     dynSizes[zoneI]++;
00198                 }
00199             }
00200             else
00201             {
00202                 dynFaces.append(Face(vertices));
00203                 dynZones.append(zoneI);
00204                 dynSizes[zoneI]++;
00205             }
00206         }
00207     }
00208     mapPointId.clear();
00209 
00210     this->sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted);
00211 
00212     // add zones, culling empty ones
00213     this->addZones(dynSizes, dynNames, true);
00214     return true;
00215 }
00216 
00217 
00218 template<class Face>
00219 void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
00220 (
00221     const fileName& filename,
00222     const MeshedSurfaceProxy<Face>& surf
00223 )
00224 {
00225     const pointField& pointLst = surf.points();
00226     const List<Face>&  faceLst = surf.faces();
00227     const List<label>& faceMap = surf.faceMap();
00228 
00229     const List<surfZone>& zones =
00230     (
00231         surf.surfZones().size() > 1
00232       ? surf.surfZones()
00233       : STARCDsurfaceFormat::oneZone(faceLst)
00234     );
00235 
00236     const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
00237 
00238 
00239     fileName baseName = filename.lessExt();
00240 
00241     writePoints(OFstream(baseName + ".vrt")(), pointLst);
00242     OFstream os(baseName + ".cel");
00243     writeHeader(os, "CELL");
00244 
00245     label faceIndex = 0;
00246     forAll(zones, zoneI)
00247     {
00248         const surfZone& zone = zones[zoneI];
00249 
00250         if (useFaceMap)
00251         {
00252             forAll(zone, localFaceI)
00253             {
00254                 const Face& f = faceLst[faceMap[faceIndex++]];
00255                 writeShell(os, f, faceIndex, zoneI + 1);
00256             }
00257         }
00258         else
00259         {
00260             forAll(zone, localFaceI)
00261             {
00262                 const Face& f = faceLst[faceIndex++];
00263                 writeShell(os, f, faceIndex, zoneI + 1);
00264             }
00265         }
00266     }
00267 
00268     // write simple .inp file
00269     writeCase
00270     (
00271         OFstream(baseName + ".inp")(),
00272         pointLst,
00273         faceLst.size(),
00274         zones
00275     );
00276 }
00277 
00278 
00279 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines