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

foamToEnsight.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     foamToEnsight
00026 
00027 Description
00028     Translates FOAM data to EnSight format.
00029 
00030     An Ensight part is created for the internalMesh and for each patch.
00031 
00032 Usage
00033     - foamToEnsight [OPTION] \n
00034     Translates OpenFOAM data to Ensight format
00035 
00036     @param -ascii \n
00037     Write Ensight data in ASCII format instead of "C Binary"
00038 
00039     @param -patches patchList \n
00040     Specify particular patches to write.
00041     Specifying an empty list suppresses writing the internalMesh.
00042 
00043     @param -noPatches \n
00044     Suppress writing any patches.
00045 
00046     @param -case <dir> \n
00047     Case directory.
00048 
00049     @param -noZero \n
00050     Ignore time step 0.
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 -parallel \n
00059     Run in parallel.
00060 
00061     @param -time <time>\n
00062     Apply only to specified time.
00063 
00064     @param -help \n
00065     Display help message.
00066 
00067     @param -doc \n
00068     Display Doxygen API documentation page for this application.
00069 
00070     @param -srcDoc \n
00071     Display Doxygen source documentation page for this application.
00072 
00073 Note
00074     Parallel support for cloud data is not supported
00075     - writes to @a EnSight directory to avoid collisions with foamToEnsightParts
00076 
00077 \*---------------------------------------------------------------------------*/
00078 
00079 #include <OpenFOAM/argList.H>
00080 #include <OpenFOAM/timeSelector.H>
00081 #include <OpenFOAM/IOobjectList.H>
00082 #include <OpenFOAM/IOmanip.H>
00083 #include <OpenFOAM/OFstream.H>
00084 
00085 #include <finiteVolume/volFields.H>
00086 
00087 #include <OpenFOAM/labelIOField.H>
00088 #include <OpenFOAM/scalarIOField.H>
00089 #include <OpenFOAM/tensorIOField.H>
00090 
00091 #include "ensightMesh.H"
00092 #include "ensightField.H"
00093 
00094 #include "ensightParticlePositions.H"
00095 #include "ensightCloudField.H"
00096 
00097 #include <finiteVolume/fvc.H>
00098 
00099 using namespace Foam;
00100 
00101 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00102 
00103 bool inFileNameList
00104 (
00105     const fileNameList& nameList,
00106     const word& name
00107 )
00108 {
00109     forAll(nameList, i)
00110     {
00111         if (nameList[i] == name)
00112         {
00113             return true;
00114         }
00115     }
00116 
00117     return false;
00118 }
00119 
00120 
00121 // Main program:
00122 
00123 int main(int argc, char *argv[])
00124 {
00125     argList::validOptions.insert("ascii", "" );
00126     argList::validOptions.insert("patches", "patchList");
00127     argList::validOptions.insert("noPatches", "");
00128 
00129 #   include <OpenFOAM/addTimeOptions.H>
00130 #   include <OpenFOAM/addRegionOption.H>
00131 #   include <OpenFOAM/setRootCase.H>
00132 
00133     // Check options
00134     bool binary = !args.optionFound("ascii");
00135 
00136 #   include <OpenFOAM/createTime.H>
00137 
00138     // get the available time-steps
00139     instantList Times = runTime.times();
00140 
00141 #   include <OpenFOAM/checkTimeOptions.H>
00142 
00143     runTime.setTime(Times[startTime], startTime);
00144 
00145 #   include <OpenFOAM/createNamedMesh.H>
00146 
00147     // Mesh instance (region0 gets filtered out)
00148     fileName regionPrefix = "";
00149 
00150     if (regionName != polyMesh::defaultRegion)
00151     {
00152         regionPrefix = regionName;
00153     }
00154 
00155     const label nVolFieldTypes = 5;
00156     const word volFieldTypes[] =
00157     {
00158         volScalarField::typeName,
00159         volVectorField::typeName,
00160         volSphericalTensorField::typeName,
00161         volSymmTensorField::typeName,
00162         volTensorField::typeName
00163     };
00164 
00165     // Path to EnSight folder at case level only
00166     // - For parallel cases, data only written from master
00167     fileName ensightDir = args.rootPath()/args.globalCaseName()/"EnSight";
00168 
00169     if (Pstream::master())
00170     {
00171         if (isDir(ensightDir))
00172         {
00173             rmDir(ensightDir);
00174         }
00175 
00176         mkDir(ensightDir);
00177     }
00178 
00179     // Start of case file header output
00180     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00181 
00182     const word prepend = args.globalCaseName() + '.';
00183 
00184     OFstream *ensightCaseFilePtr = NULL;
00185     if (Pstream::master())
00186     {
00187         fileName caseFileName = prepend + "case";
00188         Info<< nl << "write case: " << caseFileName.c_str() << endl;
00189 
00190         // the case file is always ASCII
00191         ensightCaseFilePtr = new OFstream
00192         (
00193             ensightDir/caseFileName,
00194             IOstream::ASCII
00195         );
00196 
00197         *ensightCaseFilePtr
00198             << "FORMAT" << nl
00199             << "type: ensight gold" << nl << nl;
00200     }
00201 
00202     OFstream& ensightCaseFile = *ensightCaseFilePtr;
00203 
00204     // Construct the EnSight mesh
00205     ensightMesh eMesh(mesh, args, binary);
00206 
00207     // Set Time to the last time before looking for the lagrangian objects
00208     runTime.setTime(Times[Times.size()-1], Times.size()-1);
00209 
00210     IOobjectList objects(mesh, runTime.timeName());
00211 
00212 #   include "checkMeshMoving.H"
00213 
00214     wordHashSet allCloudNames;
00215     if (Pstream::master())
00216     {
00217         word geomFileName = prepend + "000";
00218 
00219         // test pre check variable if there is a moving mesh
00220         if (meshMoving)
00221         {
00222             geomFileName = prepend + "***";
00223         }
00224 
00225         ensightCaseFile
00226             << "GEOMETRY" << nl
00227             << "model:        1     "
00228             << (geomFileName + ".mesh").c_str() << nl;
00229     }
00230 
00231     // Identify if lagrangian data exists at each time, and add clouds
00232     // to the 'allCloudNames' hash set
00233     for (label n=startTime; n<endTime; n++)
00234     {
00235         runTime.setTime(Times[n], n);
00236 
00237         fileNameList cloudDirs = readDir
00238         (
00239             runTime.timePath()/regionPrefix/cloud::prefix,
00240             fileName::DIRECTORY
00241         );
00242 
00243         forAll(cloudDirs, cloudI)
00244         {
00245             IOobjectList cloudObjs
00246             (
00247                 mesh,
00248                 runTime.timeName(),
00249                 cloud::prefix/cloudDirs[cloudI]
00250             );
00251 
00252             IOobject* positionsPtr = cloudObjs.lookup("positions");
00253 
00254             if (positionsPtr)
00255             {
00256                 allCloudNames.insert(cloudDirs[cloudI]);
00257             }
00258         }
00259     }
00260 
00261     HashTable<HashTable<word> > allCloudFields;
00262     forAllConstIter(wordHashSet, allCloudNames, cloudIter)
00263     {
00264         // Add the name of the cloud(s) to the case file header
00265         if (Pstream::master())
00266         {
00267             ensightCaseFile
00268             <<  (
00269                     "measured:     1     "
00270                   + prepend
00271                   + "***."
00272                   + cloudIter.key()
00273                 ).c_str()
00274             << nl;
00275         }
00276 
00277         // Create a new hash table for each cloud
00278         allCloudFields.insert(cloudIter.key(), HashTable<word>());
00279 
00280         // Identify the new cloud in the hash table
00281         HashTable<HashTable<word> >::iterator newCloudIter =
00282             allCloudFields.find(cloudIter.key());
00283 
00284         // Loop over all times to build list of fields and field types
00285         // for each cloud
00286         for (label n=startTime; n<endTime; n++)
00287         {
00288             runTime.setTime(Times[n], n);
00289 
00290             IOobjectList cloudObjs
00291             (
00292                 mesh,
00293                 runTime.timeName(),
00294                 cloud::prefix/cloudIter.key()
00295             );
00296 
00297             forAllConstIter(IOobjectList, cloudObjs, fieldIter)
00298             {
00299                 const IOobject obj = *fieldIter();
00300 
00301                 if (obj.name() != "positions")
00302                 {
00303                     // Add field and field type
00304                     newCloudIter().insert
00305                     (
00306                         obj.name(),
00307                         obj.headerClassName()
00308                     );
00309                 }
00310             }
00311         }
00312     }
00313 
00314     label nTimeSteps = 0;
00315     for (label n=startTime; n<endTime; n++)
00316     {
00317         nTimeSteps++;
00318         runTime.setTime(Times[n], n);
00319         label timeIndex = n - startTime;
00320 
00321         word timeName = itoa(timeIndex);
00322         word timeFile = prepend + timeName;
00323 
00324         Info<< "Translating time = " << runTime.timeName() << nl;
00325 
00326 #       include "moveMesh.H"
00327 
00328         if (timeIndex == 0 || mesh.moving())
00329         {
00330             eMesh.write
00331             (
00332                 ensightDir,
00333                 prepend,
00334                 timeIndex,
00335                 ensightCaseFile
00336             );
00337         }
00338 
00339 
00340         // Start of field data output
00341         // ~~~~~~~~~~~~~~~~~~~~~~~~~~
00342 
00343         if (timeIndex == 0 && Pstream::master())
00344         {
00345             ensightCaseFile<< nl << "VARIABLE" << nl;
00346         }
00347 
00348 
00349         // Cell field data output
00350         // ~~~~~~~~~~~~~~~~~~~~~~
00351 
00352         for (label i=0; i<nVolFieldTypes; i++)
00353         {
00354             wordList fieldNames = objects.names(volFieldTypes[i]);
00355 
00356             for (label j=0; j<fieldNames.size(); j++)
00357             {
00358                 word fieldName = fieldNames[j];
00359 
00360 #               include "checkData.H"
00361 
00362                 if (!variableGood)
00363                 {
00364                     continue;
00365                 }
00366 
00367                 IOobject fieldObject
00368                 (
00369                     fieldName,
00370                     mesh.time().timeName(),
00371                     mesh,
00372                     IOobject::MUST_READ,
00373                     IOobject::NO_WRITE
00374                 );
00375 
00376                 if (volFieldTypes[i] == volScalarField::typeName)
00377                 {
00378                     ensightField<scalar>
00379                     (
00380                         fieldObject,
00381                         eMesh,
00382                         ensightDir,
00383                         prepend,
00384                         timeIndex,
00385                         binary,
00386                         ensightCaseFile
00387                     );
00388                 }
00389                 else if (volFieldTypes[i] == volVectorField::typeName)
00390                 {
00391                     ensightField<vector>
00392                     (
00393                         fieldObject,
00394                         eMesh,
00395                         ensightDir,
00396                         prepend,
00397                         timeIndex,
00398                         binary,
00399                         ensightCaseFile
00400                     );
00401                 }
00402                 else if (volFieldTypes[i] == volSphericalTensorField::typeName)
00403                 {
00404                     ensightField<sphericalTensor>
00405                     (
00406                         fieldObject,
00407                         eMesh,
00408                         ensightDir,
00409                         prepend,
00410                         timeIndex,
00411                         binary,
00412                         ensightCaseFile
00413                     );
00414                 }
00415                 else if (volFieldTypes[i] == volSymmTensorField::typeName)
00416                 {
00417                     ensightField<symmTensor>
00418                     (
00419                         fieldObject,
00420                         eMesh,
00421                         ensightDir,
00422                         prepend,
00423                         timeIndex,
00424                         binary,
00425                         ensightCaseFile
00426                     );
00427                 }
00428                 else if (volFieldTypes[i] == volTensorField::typeName)
00429                 {
00430                     ensightField<tensor>
00431                     (
00432                         fieldObject,
00433                         eMesh,
00434                         ensightDir,
00435                         prepend,
00436                         timeIndex,
00437                         binary,
00438                         ensightCaseFile
00439                     );
00440                 }
00441             }
00442         }
00443 
00444 
00445         // Cloud field data output
00446         // ~~~~~~~~~~~~~~~~~~~~~~~
00447 
00448         forAllConstIter(HashTable<HashTable<word> >, allCloudFields, cloudIter)
00449         {
00450             const word& cloudName = cloudIter.key();
00451 
00452             fileNameList currentCloudDirs = readDir
00453             (
00454                 runTime.timePath()/regionPrefix/cloud::prefix,
00455                 fileName::DIRECTORY
00456             );
00457 
00458             bool cloudExists = inFileNameList(currentCloudDirs, cloudName);
00459             ensightParticlePositions
00460             (
00461                 mesh,
00462                 ensightDir,
00463                 timeFile,
00464                 cloudName,
00465                 cloudExists
00466             );
00467 
00468             forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
00469             {
00470                 const word& fieldName = fieldIter.key();
00471                 const word& fieldType = fieldIter();
00472 
00473                 IOobject fieldObject
00474                 (
00475                     fieldName,
00476                     mesh.time().timeName(),
00477                     cloud::prefix/cloudName,
00478                     mesh,
00479                     IOobject::MUST_READ
00480                 );
00481 
00482                 bool fieldExists = fieldObject.headerOk();
00483                 if (fieldType == scalarIOField::typeName)
00484                 {
00485                     ensightCloudField<scalar>
00486                     (
00487                         fieldObject,
00488                         ensightDir,
00489                         prepend,
00490                         timeIndex,
00491                         cloudName,
00492                         ensightCaseFile,
00493                         fieldExists
00494                     );
00495                 }
00496                 else if (fieldType == vectorIOField::typeName)
00497                 {
00498                     ensightCloudField<vector>
00499                     (
00500                         fieldObject,
00501                         ensightDir,
00502                         prepend,
00503                         timeIndex,
00504                         cloudName,
00505                         ensightCaseFile,
00506                         fieldExists
00507                     );
00508                 }
00509                 else
00510                 {
00511                     Info<< "Unable to convert field type " << fieldType
00512                         << " for field " << fieldName << endl;
00513                 }
00514             }
00515         }
00516     }
00517 
00518 #   include "ensightCaseTail.H"
00519 
00520     if (Pstream::master())
00521     {
00522         delete ensightCaseFilePtr;
00523     }
00524 
00525     Info<< "End\n" << endl;
00526 
00527     return 0;
00528 }
00529 
00530 
00531 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines