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

foamToEnsightParts.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     foamToEnsightParts
00026 
00027 Description
00028     Translates OpenFOAM data to Ensight format.
00029     An Ensight part is created for each cellZone and patch.
00030 
00031 Usage
00032     - foamToEnsightParts [OPTION] \n
00033     Translates OpenFOAM data to Ensight format
00034 
00035     @param -ascii \n
00036     Write Ensight data in ASCII format instead of "C Binary"
00037 
00038     @param -noZero \n
00039     Exclude the often incomplete initial conditions.
00040 
00041     @param -index <start>\n
00042     Ignore the time index contained in the time file and use a
00043     simple indexing when creating the @c Ensight/data/######## files.
00044 
00045     @param -noMesh \n
00046     Suppress writing the geometry. Can be useful for converting partial
00047     results for a static geometry.
00048 
00049     @param -case <dir> \n
00050     Case directory.
00051 
00052     @param -constant \n
00053     Include the constant directory.
00054 
00055     @param -latestTime \n
00056     Only apply to the latest time step.
00057 
00058     @param -time <time>\n
00059     Apply only to specified time.
00060 
00061     @param -help \n
00062     Display help message.
00063 
00064     @param -doc \n
00065     Display Doxygen API documentation page for this application.
00066 
00067     @param -srcDoc \n
00068     Display Doxygen source documentation page for this application.
00069 
00070 Note
00071     - no parallel data.
00072     - writes to @a Ensight directory to avoid collisions with foamToEnsight.
00073 
00074 \*---------------------------------------------------------------------------*/
00075 
00076 #include <OpenFOAM/argList.H>
00077 #include <OpenFOAM/timeSelector.H>
00078 
00079 #include <finiteVolume/volFields.H>
00080 #include <OpenFOAM/OFstream.H>
00081 #include <OpenFOAM/IOmanip.H>
00082 #include <OpenFOAM/IOobjectList.H>
00083 #include <OpenFOAM/scalarIOField.H>
00084 #include <OpenFOAM/tensorIOField.H>
00085 
00086 #include <conversion/ensightParts.H>
00087 #include "ensightOutputFunctions.H"
00088 
00089 using namespace Foam;
00090 
00091 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00092 
00093 // Main program:
00094 
00095 int main(int argc, char *argv[])
00096 {
00097     // enable -constant
00098     // probably don't need -zeroTime though, since the fields are vetted
00099     // afterwards anyhow
00100     timeSelector::addOptions(true, false);
00101     argList::noParallel();
00102     argList::validOptions.insert("ascii", "");
00103     argList::validOptions.insert("index",  "start");
00104     argList::validOptions.insert("noMesh", "");
00105 
00106     // the volume field types that we handle
00107     wordHashSet volFieldTypes;
00108     volFieldTypes.insert(volScalarField::typeName);
00109     volFieldTypes.insert(volVectorField::typeName);
00110     volFieldTypes.insert(volSphericalTensorField::typeName);
00111     volFieldTypes.insert(volSymmTensorField::typeName);
00112     volFieldTypes.insert(volTensorField::typeName);
00113 
00114     // the lagrangian field types that we handle
00115     wordHashSet cloudFieldTypes;
00116     cloudFieldTypes.insert(scalarIOField::typeName);
00117     cloudFieldTypes.insert(vectorIOField::typeName);
00118     cloudFieldTypes.insert(tensorIOField::typeName);
00119 
00120     const char* geometryName = "geometry";
00121 
00122 #   include <OpenFOAM/setRootCase.H>
00123 #   include <OpenFOAM/createTime.H>
00124 
00125     // get times list
00126     instantList timeDirs = timeSelector::select0(runTime, args);
00127 
00128     // default to binary output, unless otherwise specified
00129     IOstream::streamFormat format = IOstream::BINARY;
00130     if (args.optionFound("ascii"))
00131     {
00132         format = IOstream::ASCII;
00133     }
00134 
00135     // control for renumbering iterations
00136     bool optIndex = false;
00137     label indexingNumber = 0;
00138     if (args.optionFound("index"))
00139     {
00140         optIndex = true;
00141         indexingNumber = args.optionRead<label>("index");
00142     }
00143 
00144     // always write the geometry, unless the -noMesh option is specified
00145     bool optNoMesh = args.optionFound("noMesh");
00146 
00147     fileName ensightDir = args.rootPath()/args.globalCaseName()/"Ensight";
00148     fileName dataDir = ensightDir/"data";
00149     fileName caseFileName = "Ensight.case";
00150     fileName dataMask = fileName("data")/ensightFile::mask();
00151 
00152     // Ensight and Ensight/data directories must exist
00153     // do not remove old data - we might wish to convert new results
00154     // or a particular time interval
00155     if (isDir(ensightDir))
00156     {
00157         Info<<"Warning: reusing existing directory" << nl
00158             << "    " << ensightDir << endl;
00159     }
00160     mkDir(ensightDir);
00161     mkDir(dataDir);
00162 
00163 #   include <OpenFOAM/createNamedMesh.H>
00164 
00165     // Mesh instance (region0 gets filtered out)
00166     fileName regionPrefix;
00167 
00168     if (regionName != polyMesh::defaultRegion)
00169     {
00170         regionPrefix = regionName;
00171     }
00172 
00173     // Construct the list of ensight parts for the entire mesh
00174     ensightParts partsList(mesh);
00175 
00176     // write summary information
00177     {
00178         OFstream partsInfoFile(ensightDir/"partsInfo");
00179 
00180         partsInfoFile
00181             << "// summary of ensight parts" << nl << nl;
00182         partsList.writeSummary(partsInfoFile);
00183     }
00184 
00185 #   include "checkHasMovingMesh.H"
00186 #   include "findFields.H"
00187 
00188     if (hasMovingMesh && optNoMesh)
00189     {
00190         Info<< "mesh is moving: ignoring '-noMesh' option" << endl;
00191         optNoMesh = false;
00192     }
00193 
00194 
00195     // map times used
00196     Map<scalar>  timeIndices;
00197 
00198     // Track the time indices used by the volume fields
00199     DynamicList<label> fieldTimesUsed;
00200 
00201     // Track the time indices used by each cloud
00202     // Use autoPtr to help GCC compilers (< 4.3) which suffer from core
00203     // language defect 391, i.e. require a copy-ctor to be present when passing
00204     // a temporary as an rvalue.
00205     HashTable<autoPtr<DynamicList<label> > > cloudTimesUsed;
00206 
00207     // Create a new DynamicList for each cloud
00208     forAllConstIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
00209     {
00210         cloudTimesUsed.insert(cloudIter.key(),
00211                 autoPtr<DynamicList<label> >(new DynamicList<label>()));
00212     }
00213 
00214 
00215     forAll(timeDirs, timeI)
00216     {
00217         runTime.setTime(timeDirs[timeI], timeI);
00218 
00219 #       include "getTimeIndex.H"
00220 
00221         // remember the time index
00222         fieldTimesUsed.append(timeIndex);
00223 
00224         // the data/ITER subdirectory must exist
00225         fileName subDir = ensightFile::subDir(timeIndex);
00226         mkDir(dataDir/subDir);
00227 
00228         // place a timestamp in the directory for future reference
00229         {
00230             OFstream timeStamp(dataDir/subDir/"time");
00231             timeStamp
00232                 << "#   timestep time" << nl
00233                 << subDir.c_str() << " " << runTime.timeName() << nl;
00234         }
00235 
00236 #       include "moveMesh.H"
00237 
00238         if (timeI == 0 || mesh.moving())
00239         {
00240             if (mesh.moving())
00241             {
00242                 partsList.recalculate(mesh);
00243             }
00244 
00245             if (!optNoMesh)
00246             {
00247                 fileName geomDir;
00248                 if (hasMovingMesh)
00249                 {
00250                     geomDir = dataDir/subDir;
00251                 }
00252 
00253                 ensightGeoFile geoFile(ensightDir/geomDir/geometryName, format);
00254                 partsList.writeGeometry(geoFile);
00255                 Info<< nl;
00256             }
00257         }
00258 
00259         Info<< "write volume field (" << flush;
00260 
00261         forAllConstIter(HashTable<word>, volumeFields, fieldIter)
00262         {
00263             const word& fieldName = fieldIter.key();
00264             const word& fieldType = fieldIter();
00265 
00266             IOobject fieldObject
00267             (
00268                 fieldName,
00269                 mesh.time().timeName(),
00270                 mesh,
00271                 IOobject::MUST_READ,
00272                 IOobject::NO_WRITE
00273             );
00274 
00275             if (fieldType == volScalarField::typeName)
00276             {
00277                 ensightVolField<scalar>
00278                 (
00279                     partsList,
00280                     fieldObject,
00281                     mesh,
00282                     dataDir,
00283                     subDir,
00284                     format
00285                 );
00286 
00287             }
00288             else if (fieldType == volVectorField::typeName)
00289             {
00290                 ensightVolField<vector>
00291                 (
00292                     partsList,
00293                     fieldObject,
00294                     mesh,
00295                     dataDir,
00296                     subDir,
00297                     format
00298                 );
00299 
00300             }
00301             else if (fieldType == volSphericalTensorField::typeName)
00302             {
00303                 ensightVolField<sphericalTensor>
00304                 (
00305                     partsList,
00306                     fieldObject,
00307                     mesh,
00308                     dataDir,
00309                     subDir,
00310                     format
00311                 );
00312 
00313             }
00314             else if (fieldType == volSymmTensorField::typeName)
00315             {
00316                 ensightVolField<symmTensor>
00317                 (
00318                     partsList,
00319                     fieldObject,
00320                     mesh,
00321                     dataDir,
00322                     subDir,
00323                     format
00324                 );
00325             }
00326             else if (fieldType == volTensorField::typeName)
00327             {
00328                 ensightVolField<tensor>
00329                 (
00330                     partsList,
00331                     fieldObject,
00332                     mesh,
00333                     dataDir,
00334                     subDir,
00335                     format
00336                 );
00337             }
00338         }
00339         Info<< " )" << endl;
00340 
00341         // check for clouds
00342         forAllConstIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
00343         {
00344             const word& cloudName = cloudIter.key();
00345 
00346             if
00347             (
00348                 !isDir
00349                 (
00350                     runTime.timePath()/regionPrefix/
00351                     cloud::prefix/cloudName
00352                 )
00353             )
00354             {
00355                 continue;
00356             }
00357 
00358             IOobjectList cloudObjs
00359             (
00360                 mesh,
00361                 runTime.timeName(),
00362                 cloud::prefix/cloudName
00363             );
00364 
00365             // check that the positions field is present for this time
00366             if (cloudObjs.lookup("positions"))
00367             {
00368                 ensightParticlePositions
00369                 (
00370                     mesh,
00371                     dataDir,
00372                     subDir,
00373                     cloudName,
00374                     format
00375                 );
00376             }
00377             else
00378             {
00379                 continue;
00380             }
00381 
00382             Info<< "write " << cloudName << " (" << flush;
00383 
00384             forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
00385             {
00386                 const word& fieldName = fieldIter.key();
00387                 const word& fieldType = fieldIter();
00388 
00389                 IOobject *fieldObject = cloudObjs.lookup(fieldName);
00390 
00391                 if (!fieldObject)
00392                 {
00393                     Info<< "missing "
00394                         << runTime.timeName()/cloud::prefix/cloudName
00395                         / fieldName
00396                         << endl;
00397                     continue;
00398                 }
00399 
00400                 if (fieldType == scalarIOField::typeName)
00401                 {
00402                     ensightLagrangianField<scalar>
00403                     (
00404                         *fieldObject,
00405                         dataDir,
00406                         subDir,
00407                         cloudName,
00408                         format
00409                     );
00410 
00411                 }
00412                 else if (fieldType == vectorIOField::typeName)
00413                 {
00414                     ensightLagrangianField<vector>
00415                     (
00416                         *fieldObject,
00417                         dataDir,
00418                         subDir,
00419                         cloudName,
00420                         format
00421                     );
00422 
00423                 }
00424                 else if (fieldType == tensorIOField::typeName)
00425                 {
00426                     ensightLagrangianField<tensor>
00427                     (
00428                         *fieldObject,
00429                         dataDir,
00430                         subDir,
00431                         cloudName,
00432                         format
00433                     );
00434 
00435                 }
00436             }
00437 
00438             Info<< " )" << endl;
00439 
00440             // remember the time index
00441             cloudTimesUsed[cloudName]->append(timeIndex);
00442         }
00443     }
00444 
00445 #   include "ensightOutputCase.H"
00446 
00447     Info<< "\nEnd\n"<< endl;
00448 
00449     return 0;
00450 }
00451 
00452 
00453 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines