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

mapFields.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     mapFields
00026 
00027 Description
00028     Maps volume fields from one mesh to another.
00029 
00030     Maps volume fields from one mesh to another, reading and
00031     interpolating all fields present in the time directory of both cases.
00032     Parallel and non-parallel cases are handled without the need to reconstruct
00033     them first.
00034 
00035 Usage
00036 
00037     - mapFields [OPTIONS] <source dir>
00038 
00039     @param <source dir> \n
00040     @todo Detailed description of argument.
00041 
00042     @param -consistent \n
00043     Meshes are consistent.
00044 
00045     @param -parallelSource \n
00046     The source case is decomposed.
00047 
00048     @param -sourceTime <scalar>\n
00049     Time of the source.
00050 
00051     @param -parallelTarget \n
00052     The target case is decomposed.
00053 
00054     @param -case <dir>\n
00055     Case directory.
00056 
00057     @param -help \n
00058     Display help message.
00059 
00060     @param -doc \n
00061     Display Doxygen API documentation page for this application.
00062 
00063     @param -srcDoc \n
00064     Display Doxygen source documentation page for this application.
00065 
00066 \*---------------------------------------------------------------------------*/
00067 
00068 #include <finiteVolume/fvCFD.H>
00069 #include <sampling/meshToMesh.H>
00070 #include "MapVolFields.H"
00071 #include "MapConsistentVolFields.H"
00072 #include "UnMapped.H"
00073 #include <finiteVolume/processorFvPatch.H>
00074 #include "mapLagrangian.H"
00075 
00076 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00077 
00078 void mapConsistentMesh
00079 (
00080     const fvMesh& meshSource,
00081     const fvMesh& meshTarget
00082 )
00083 {
00084     // Create the interpolation scheme
00085     meshToMesh meshToMeshInterp(meshSource, meshTarget);
00086 
00087     Info<< nl
00088         << "Consistently creating and mapping fields for time "
00089         << meshSource.time().timeName() << nl << endl;
00090 
00091     {
00092         // Search for list of objects for this time
00093         IOobjectList objects(meshSource, meshSource.time().timeName());
00094 
00095         // Map volFields
00096         // ~~~~~~~~~~~~~
00097         MapConsistentVolFields<scalar>(objects, meshToMeshInterp);
00098         MapConsistentVolFields<vector>(objects, meshToMeshInterp);
00099         MapConsistentVolFields<sphericalTensor>(objects, meshToMeshInterp);
00100         MapConsistentVolFields<symmTensor>(objects, meshToMeshInterp);
00101         MapConsistentVolFields<tensor>(objects, meshToMeshInterp);
00102     }
00103 
00104     {
00105         // Search for list of target objects for this time
00106         IOobjectList objects(meshTarget, meshTarget.time().timeName());
00107 
00108         // Mark surfaceFields as unmapped
00109         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00110         UnMapped<surfaceScalarField>(objects);
00111         UnMapped<surfaceVectorField>(objects);
00112         UnMapped<surfaceSphericalTensorField>(objects);
00113         UnMapped<surfaceSymmTensorField>(objects);
00114         UnMapped<surfaceTensorField>(objects);
00115 
00116         // Mark pointFields as unmapped
00117         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00118         UnMapped<pointScalarField>(objects);
00119         UnMapped<pointVectorField>(objects);
00120         UnMapped<pointSphericalTensorField>(objects);
00121         UnMapped<pointSymmTensorField>(objects);
00122         UnMapped<pointTensorField>(objects);
00123     }
00124 
00125     mapLagrangian(meshToMeshInterp);
00126 }
00127 
00128 
00129 void mapSubMesh
00130 (
00131     const fvMesh& meshSource,
00132     const fvMesh& meshTarget,
00133     const HashTable<word>& patchMap,
00134     const wordList& cuttingPatches
00135 )
00136 {
00137     // Create the interpolation scheme
00138     meshToMesh meshToMeshInterp
00139     (
00140         meshSource,
00141         meshTarget,
00142         patchMap,
00143         cuttingPatches
00144     );
00145 
00146     Info<< nl
00147         << "Mapping fields for time " << meshSource.time().timeName()
00148         << nl << endl;
00149 
00150     {
00151         // Search for list of source objects for this time
00152         IOobjectList objects(meshSource, meshSource.time().timeName());
00153 
00154         // Map volFields
00155         // ~~~~~~~~~~~~~
00156         MapVolFields<scalar>(objects, meshToMeshInterp);
00157         MapVolFields<vector>(objects, meshToMeshInterp);
00158         MapVolFields<sphericalTensor>(objects, meshToMeshInterp);
00159         MapVolFields<symmTensor>(objects, meshToMeshInterp);
00160         MapVolFields<tensor>(objects, meshToMeshInterp);
00161     }
00162 
00163     {
00164         // Search for list of target objects for this time
00165         IOobjectList objects(meshTarget, meshTarget.time().timeName());
00166 
00167         // Mark surfaceFields as unmapped
00168         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00169         UnMapped<surfaceScalarField>(objects);
00170         UnMapped<surfaceVectorField>(objects);
00171         UnMapped<surfaceSphericalTensorField>(objects);
00172         UnMapped<surfaceSymmTensorField>(objects);
00173         UnMapped<surfaceTensorField>(objects);
00174 
00175         // Mark pointFields as unmapped
00176         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00177         UnMapped<pointScalarField>(objects);
00178         UnMapped<pointVectorField>(objects);
00179         UnMapped<pointSphericalTensorField>(objects);
00180         UnMapped<pointSymmTensorField>(objects);
00181         UnMapped<pointTensorField>(objects);
00182     }
00183 
00184     mapLagrangian(meshToMeshInterp);
00185 }
00186 
00187 
00188 void mapConsistentSubMesh
00189 (
00190     const fvMesh& meshSource,
00191     const fvMesh& meshTarget
00192 )
00193 {
00194     HashTable<word> patchMap;
00195     HashTable<label> cuttingPatchTable;
00196 
00197     forAll(meshTarget.boundary(), patchi)
00198     {
00199         if (!isA<processorFvPatch>(meshTarget.boundary()[patchi]))
00200         {
00201             patchMap.insert
00202             (
00203                 meshTarget.boundary()[patchi].name(),
00204                 meshTarget.boundary()[patchi].name()
00205             );
00206         }
00207         else
00208         {
00209             cuttingPatchTable.insert
00210             (
00211                 meshTarget.boundaryMesh()[patchi].name(),
00212                 -1
00213             );
00214         }
00215     }
00216 
00217     mapSubMesh(meshSource, meshTarget, patchMap, cuttingPatchTable.toc());
00218 }
00219 
00220 
00221 wordList addProcessorPatches
00222 (
00223     const fvMesh& meshTarget,
00224     const wordList& cuttingPatches
00225 )
00226 {
00227     // Add the processor patches to the cutting list
00228     HashTable<label> cuttingPatchTable;
00229     forAll (cuttingPatches, i)
00230     {
00231         cuttingPatchTable.insert(cuttingPatches[i], i);
00232     }
00233 
00234     forAll (meshTarget.boundary(), patchi)
00235     {
00236         if (isA<processorFvPatch>(meshTarget.boundary()[patchi]))
00237         {
00238             if
00239             (
00240                !cuttingPatchTable.found
00241                 (
00242                     meshTarget.boundaryMesh()[patchi].name()
00243                 )
00244             )
00245             {
00246                 cuttingPatchTable.insert
00247                 (
00248                     meshTarget.boundaryMesh()[patchi].name(),
00249                     -1
00250                 );
00251             }
00252         }
00253     }
00254 
00255     return cuttingPatchTable.toc();
00256 }
00257 
00258 
00259 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00260 
00261 int main(int argc, char *argv[])
00262 {
00263     #include "setRoots.H"
00264     #include "createTimes.H"
00265 
00266     HashTable<word> patchMap;
00267     wordList cuttingPatches;
00268 
00269     if (!consistent)
00270     {
00271         IOdictionary mapFieldsDict
00272         (
00273             IOobject
00274             (
00275                 "mapFieldsDict",
00276                 runTimeTarget.system(),
00277                 runTimeTarget,
00278                 IOobject::MUST_READ,
00279                 IOobject::NO_WRITE,
00280                 false
00281             )
00282         );
00283 
00284         mapFieldsDict.lookup("patchMap") >> patchMap;
00285 
00286         mapFieldsDict.lookup("cuttingPatches") >>  cuttingPatches;
00287     }
00288 
00289     if (parallelSource && !parallelTarget)
00290     {
00291         IOdictionary decompositionDict
00292         (
00293             IOobject
00294             (
00295                 "decomposeParDict",
00296                 runTimeSource.system(),
00297                 runTimeSource,
00298                 IOobject::MUST_READ,
00299                 IOobject::NO_WRITE
00300             )
00301         );
00302 
00303         int nProcs(readInt(decompositionDict.lookup("numberOfSubdomains")));
00304 
00305         Info<< "Create target mesh\n" << endl;
00306 
00307         fvMesh meshTarget
00308         (
00309             IOobject
00310             (
00311                 fvMesh::defaultRegion,
00312                 runTimeTarget.timeName(),
00313                 runTimeTarget
00314             )
00315         );
00316 
00317         Info<< "Target mesh size: " << meshTarget.nCells() << endl;
00318 
00319         for (int procI=0; procI<nProcs; procI++)
00320         {
00321             Info<< nl << "Source processor " << procI << endl;
00322 
00323             Time runTimeSource
00324             (
00325                 Time::controlDictName,
00326                 rootDirSource,
00327                 caseDirSource/fileName(word("processor") + name(procI))
00328             );
00329 
00330             #include "setTimeIndex.H"
00331 
00332             fvMesh meshSource
00333             (
00334                 IOobject
00335                 (
00336                     fvMesh::defaultRegion,
00337                     runTimeSource.timeName(),
00338                     runTimeSource
00339                 )
00340             );
00341 
00342             Info<< "mesh size: " << meshSource.nCells() << endl;
00343 
00344             if (consistent)
00345             {
00346                 mapConsistentSubMesh(meshSource, meshTarget);
00347             }
00348             else
00349             {
00350                 mapSubMesh(meshSource, meshTarget, patchMap, cuttingPatches);
00351             }
00352         }
00353     }
00354     else if (!parallelSource && parallelTarget)
00355     {
00356         IOdictionary decompositionDict
00357         (
00358             IOobject
00359             (
00360                 "decomposeParDict",
00361                 runTimeTarget.system(),
00362                 runTimeTarget,
00363                 IOobject::MUST_READ,
00364                 IOobject::NO_WRITE
00365             )
00366         );
00367 
00368         int nProcs(readInt(decompositionDict.lookup("numberOfSubdomains")));
00369 
00370         Info<< "Create source mesh\n" << endl;
00371 
00372         #include "setTimeIndex.H"
00373 
00374         fvMesh meshSource
00375         (
00376             IOobject
00377             (
00378                 fvMesh::defaultRegion,
00379                 runTimeSource.timeName(),
00380                 runTimeSource
00381             )
00382         );
00383 
00384         Info<< "Source mesh size: " << meshSource.nCells() << endl;
00385 
00386         for (int procI=0; procI<nProcs; procI++)
00387         {
00388             Info<< nl << "Target processor " << procI << endl;
00389 
00390             Time runTimeTarget
00391             (
00392                 Time::controlDictName,
00393                 rootDirTarget,
00394                 caseDirTarget/fileName(word("processor") + name(procI))
00395             );
00396 
00397             fvMesh meshTarget
00398             (
00399                 IOobject
00400                 (
00401                     fvMesh::defaultRegion,
00402                     runTimeTarget.timeName(),
00403                     runTimeTarget
00404                 )
00405             );
00406 
00407             Info<< "mesh size: " << meshTarget.nCells() << endl;
00408 
00409             if (consistent)
00410             {
00411                 mapConsistentSubMesh(meshSource, meshTarget);
00412             }
00413             else
00414             {
00415                 mapSubMesh
00416                 (
00417                     meshSource,
00418                     meshTarget,
00419                     patchMap,
00420                     addProcessorPatches(meshTarget, cuttingPatches)
00421                 );
00422             }
00423         }
00424     }
00425     else if (parallelSource && parallelTarget)
00426     {
00427         IOdictionary decompositionDictSource
00428         (
00429             IOobject
00430             (
00431                 "decomposeParDict",
00432                 runTimeSource.system(),
00433                 runTimeSource,
00434                 IOobject::MUST_READ,
00435                 IOobject::NO_WRITE
00436             )
00437         );
00438 
00439         int nProcsSource
00440         (
00441             readInt(decompositionDictSource.lookup("numberOfSubdomains"))
00442         );
00443 
00444 
00445         IOdictionary decompositionDictTarget
00446         (
00447             IOobject
00448             (
00449                 "decomposeParDict",
00450                 runTimeTarget.system(),
00451                 runTimeTarget,
00452                 IOobject::MUST_READ,
00453                 IOobject::NO_WRITE
00454             )
00455         );
00456 
00457         int nProcsTarget
00458         (
00459             readInt(decompositionDictTarget.lookup("numberOfSubdomains"))
00460         );
00461 
00462         List<boundBox> bbsTarget(nProcsTarget);
00463         List<bool> bbsTargetSet(nProcsTarget, false);
00464 
00465         for (int procISource=0; procISource<nProcsSource; procISource++)
00466         {
00467             Info<< nl << "Source processor " << procISource << endl;
00468 
00469             Time runTimeSource
00470             (
00471                 Time::controlDictName,
00472                 rootDirSource,
00473                 caseDirSource/fileName(word("processor") + name(procISource))
00474             );
00475 
00476             #include "setTimeIndex.H"
00477 
00478             fvMesh meshSource
00479             (
00480                 IOobject
00481                 (
00482                     fvMesh::defaultRegion,
00483                     runTimeSource.timeName(),
00484                     runTimeSource
00485                 )
00486             );
00487 
00488             Info<< "mesh size: " << meshSource.nCells() << endl;
00489 
00490             boundBox bbSource(meshSource.bounds());
00491 
00492             for (int procITarget=0; procITarget<nProcsTarget; procITarget++)
00493             {
00494                 if
00495                 (
00496                     !bbsTargetSet[procITarget]
00497                   || (
00498                       bbsTargetSet[procITarget]
00499                    && bbsTarget[procITarget].overlaps(bbSource)
00500                      )
00501                 )
00502                 {
00503                     Info<< nl << "Target processor " << procITarget << endl;
00504 
00505                     Time runTimeTarget
00506                     (
00507                         Time::controlDictName,
00508                         rootDirTarget,
00509                         caseDirTarget/fileName(word("processor")
00510                       + name(procITarget))
00511                     );
00512 
00513                     fvMesh meshTarget
00514                     (
00515                         IOobject
00516                         (
00517                             fvMesh::defaultRegion,
00518                             runTimeTarget.timeName(),
00519                             runTimeTarget
00520                         )
00521                     );
00522 
00523                     Info<< "mesh size: " << meshTarget.nCells() << endl;
00524 
00525                     bbsTarget[procITarget] = meshTarget.bounds();
00526                     bbsTargetSet[procITarget] = true;
00527 
00528                     if (bbsTarget[procITarget].overlaps(bbSource))
00529                     {
00530                         if (consistent)
00531                         {
00532                             mapConsistentSubMesh(meshSource, meshTarget);
00533                         }
00534                         else
00535                         {
00536                             mapSubMesh
00537                             (
00538                                 meshSource,
00539                                 meshTarget,
00540                                 patchMap,
00541                                 addProcessorPatches(meshTarget, cuttingPatches)
00542                             );
00543                         }
00544                     }
00545                 }
00546             }
00547         }
00548     }
00549     else
00550     {
00551         #include "setTimeIndex.H"
00552 
00553         Info<< "Create meshes\n" << endl;
00554 
00555         fvMesh meshSource
00556         (
00557             IOobject
00558             (
00559                 fvMesh::defaultRegion,
00560                 runTimeSource.timeName(),
00561                 runTimeSource
00562             )
00563         );
00564 
00565         fvMesh meshTarget
00566         (
00567             IOobject
00568             (
00569                 fvMesh::defaultRegion,
00570                 runTimeTarget.timeName(),
00571                 runTimeTarget
00572             )
00573         );
00574 
00575         Info<< "Source mesh size: " << meshSource.nCells() << tab
00576             << "Target mesh size: " << meshTarget.nCells() << nl << endl;
00577 
00578         if (consistent)
00579         {
00580             mapConsistentMesh(meshSource, meshTarget);
00581         }
00582         else
00583         {
00584             mapSubMesh(meshSource, meshTarget, patchMap, cuttingPatches);
00585         }
00586     }
00587 
00588     Info<< "\nEnd\n" << endl;
00589 
00590     return 0;
00591 }
00592 
00593 
00594 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines