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

plot3dToFoam.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 Application
00025     plot3dToFoam
00026 
00027 Description
00028     Plot3d mesh (ascii/formatted format) converter.
00029 
00030     Work in progress! Handles ascii multiblock (and optionally singleBlock)
00031     format.
00032     By default expects blanking. Use -noBlank if none.
00033     Use -2D @a thickness if 2D.
00034 
00035     Niklas Nordin has experienced a problem with lefthandedness of the blocks.
00036     The code should detect this automatically - see hexBlock::readPoints but
00037     if this goes wrong just set the blockHandedness_ variable to 'right'
00038     always.
00039 
00040 Usage
00041 
00042     - plot3dToFoam [OPTIONS] <PLOT3D geom file>
00043 
00044     @param <PLOT3D geom file> \n
00045     @todo Detailed description of argument.
00046 
00047     @param -noBlank \n
00048     Do not expect blanking.
00049 
00050     @param -2D <thickness>\n
00051     Data is 2D.
00052 
00053     @param -singleBlock \n
00054     Data is in a single block.
00055 
00056     @param -scale <number>\n
00057     Scale factor.
00058 
00059     @param -case <dir>\n
00060     Case directory.
00061 
00062     @param -help \n
00063     Display help message.
00064 
00065     @param -doc \n
00066     Display Doxygen API documentation page for this application.
00067 
00068     @param -srcDoc \n
00069     Display Doxygen source documentation page for this application.
00070 
00071 \*---------------------------------------------------------------------------*/
00072 
00073 #include <OpenFOAM/argList.H>
00074 #include <OpenFOAM/Time.H>
00075 #include <OpenFOAM/IFstream.H>
00076 #include "hexBlock.H"
00077 #include <OpenFOAM/polyMesh.H>
00078 #include <OpenFOAM/wallPolyPatch.H>
00079 #include <OpenFOAM/symmetryPolyPatch.H>
00080 #include <OpenFOAM/preservePatchTypes.H>
00081 #include <OpenFOAM/cellShape.H>
00082 #include <OpenFOAM/cellModeller.H>
00083 #include <OpenFOAM/mergePoints.H>
00084 
00085 using namespace Foam;
00086 
00087 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00088 // Main program:
00089 
00090 int main(int argc, char *argv[])
00091 {
00092     argList::noParallel();
00093     argList::validArgs.append("PLOT3D geom file");
00094     argList::validOptions.insert("scale", "scale factor");
00095     argList::validOptions.insert("noBlank", "");
00096     argList::validOptions.insert("singleBlock", "");
00097     argList::validOptions.insert("2D", "thickness");
00098 
00099     argList args(argc, argv);
00100 
00101     if (!args.check())
00102     {
00103          FatalError.exit();
00104     }
00105 
00106     scalar scaleFactor = 1.0;
00107     args.optionReadIfPresent("scale", scaleFactor);
00108 
00109     bool readBlank = !args.optionFound("noBlank");
00110     bool singleBlock = args.optionFound("singleBlock");
00111     scalar twoDThickness = -1;
00112     if (args.optionReadIfPresent("2D", twoDThickness))
00113     {
00114         Info<< "Reading 2D case by extruding points by " << twoDThickness
00115             << " in z direction." << nl << endl;
00116     }
00117 
00118 
00119 #   include <OpenFOAM/createTime.H>
00120 
00121     IFstream plot3dFile(args.additionalArgs()[0]);
00122 
00123     // Read the plot3d information using a fixed format reader.
00124     // Comments in the file are in C++ style, so the stream parser will remove
00125     // them with no intervention
00126     label nblock;
00127 
00128     if (singleBlock)
00129     {
00130         nblock = 1;
00131     }
00132     else
00133     {
00134         plot3dFile >> nblock;
00135     }
00136 
00137     Info<< "Reading " << nblock << " blocks" << endl;
00138 
00139     PtrList<hexBlock> blocks(nblock);
00140 
00141     {
00142         label nx, ny, nz;
00143 
00144         forAll (blocks, blockI)
00145         {
00146             if (twoDThickness > 0)
00147             {
00148                 // Fake second set of points (done in readPoints below)
00149                 plot3dFile >> nx >> ny;
00150                 nz = 2;
00151             }
00152             else
00153             {
00154                 plot3dFile >> nx >> ny >> nz;
00155             }
00156 
00157             Info<< "block " << blockI << " nx:" << nx
00158                 << " ny:" << ny << " nz:" << nz << endl;
00159 
00160             blocks.set(blockI, new hexBlock(nx, ny, nz));
00161         }
00162     }
00163 
00164     Info<< "Reading block points" << endl;
00165     label sumPoints(0);
00166     label nMeshCells(0);
00167 
00168     forAll (blocks, blockI)
00169     {
00170         Info<< "block " << blockI << ":" << nl;
00171         blocks[blockI].readPoints(readBlank, twoDThickness, plot3dFile);
00172         sumPoints += blocks[blockI].nBlockPoints();
00173         nMeshCells += blocks[blockI].nBlockCells();
00174         Info<< nl;
00175     }
00176 
00177     pointField points(sumPoints);
00178     labelList blockOffsets(blocks.size());
00179     sumPoints = 0;
00180     forAll (blocks, blockI)
00181     {
00182         const pointField& blockPoints = blocks[blockI].points();
00183         blockOffsets[blockI] = sumPoints;
00184         forAll (blockPoints, i)
00185         {
00186             points[sumPoints++] = blockPoints[i];
00187         }
00188     }
00189 
00190     // From old to new master point
00191     labelList oldToNew;
00192     pointField newPoints;
00193 
00194     // Merge points
00195     mergePoints
00196     (
00197         points,
00198         SMALL,
00199         false,
00200         oldToNew,
00201         newPoints
00202     );
00203 
00204     Info<< "Merged points within " << SMALL << " distance. Merged from "
00205         << oldToNew.size() << " down to " << newPoints.size()
00206         << " points." << endl;
00207 
00208     // Scale the points
00209     if (scaleFactor > 1.0 + SMALL || scaleFactor < 1.0 - SMALL)
00210     {
00211         newPoints *= scaleFactor;
00212     }
00213 
00214     Info<< "Creating cells" << endl;
00215 
00216     cellShapeList cellShapes(nMeshCells);
00217 
00218     const cellModel& hex = *(cellModeller::lookup("hex"));
00219 
00220     label nCreatedCells = 0;
00221 
00222     forAll (blocks, blockI)
00223     {
00224         labelListList curBlockCells = blocks[blockI].blockCells();
00225 
00226         forAll (curBlockCells, blockCellI)
00227         {
00228             labelList cellPoints(curBlockCells[blockCellI].size());
00229 
00230             forAll (cellPoints, pointI)
00231             {
00232                 cellPoints[pointI] =
00233                     oldToNew
00234                     [
00235                         curBlockCells[blockCellI][pointI]
00236                       + blockOffsets[blockI]
00237                     ];
00238             }
00239 
00240             // Do automatic collapse from hex.
00241             cellShapes[nCreatedCells] = cellShape(hex, cellPoints, true);
00242 
00243             nCreatedCells++;
00244         }
00245     }
00246 
00247     Info<< "Creating boundary patches" << endl;
00248 
00249     faceListList boundary(0);
00250     wordList patchNames(0);
00251     wordList patchTypes(0);
00252     word defaultFacesName = "defaultFaces";
00253     word defaultFacesType = wallPolyPatch::typeName;
00254     wordList patchPhysicalTypes(0);
00255 
00256     polyMesh pShapeMesh
00257     (
00258         IOobject
00259         (
00260             polyMesh::defaultRegion,
00261             runTime.constant(),
00262             runTime
00263         ),
00264         xferMove(newPoints),
00265         cellShapes,
00266         boundary,
00267         patchNames,
00268         patchTypes,
00269         defaultFacesName,
00270         defaultFacesType,
00271         patchPhysicalTypes
00272     );
00273 
00274     // Set the precision of the points data to 10
00275     IOstream::defaultPrecision(10);
00276 
00277     Info<< "Writing polyMesh" << endl;
00278     pShapeMesh.write();
00279 
00280     Info<< "End\n" << endl;
00281 
00282     return 0;
00283 }
00284 
00285 
00286 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines