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

decomposePar.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     decomposePar
00026 
00027 Description
00028     Automatically decomposes a mesh and fields of a case for parallel
00029     execution of OpenFOAM.
00030 
00031 Usage
00032 
00033     - decomposePar [OPTION]
00034 
00035     @param -cellDist \n
00036     Write the cell distribution as a labelList for use with 'manual'
00037     decomposition method and as a volScalarField for post-processing.
00038 
00039     @param -region regionName \n
00040     Decompose named region. Does not check for existence of processor*.
00041 
00042     @param -copyUniform \n
00043     Copy any @a uniform directories too.
00044 
00045     @param -fields \n
00046     Use existing geometry decomposition and convert fields only.
00047 
00048     @param -filterPatches \n
00049     Remove empty patches when decomposing the geometry.
00050 
00051     @param -force \n
00052     Remove any existing @a processor subdirectories before decomposing the
00053     geometry.
00054 
00055     @param -ifRequired \n
00056     Only decompose the geometry if the number of domains has changed from a
00057     previous decomposition. No @a processor subdirectories will be removed
00058     unless the @a -force option is also specified. This option can be used
00059     to avoid redundant geometry decomposition (eg, in scripts), but should
00060     be used with caution when the underlying (serial) geometry or the
00061     decomposition method etc. have been changed between decompositions.
00062 
00063     @param -case <dir> \n
00064     Case directory.
00065 
00066     @param -help \n
00067     Display help message.
00068 
00069     @param -doc \n
00070     Display Doxygen API documentation page for this application.
00071 
00072     @param -srcDoc \n
00073     Display Doxygen source documentation page for this application.
00074 
00075 \*---------------------------------------------------------------------------*/
00076 
00077 #include <OpenFOAM/OSspecific.H>
00078 #include <finiteVolume/fvCFD.H>
00079 #include <OpenFOAM/IOobjectList.H>
00080 #include <finiteVolume/processorFvPatchFields.H>
00081 #include "domainDecomposition.H"
00082 #include <OpenFOAM/labelIOField.H>
00083 #include <OpenFOAM/scalarIOField.H>
00084 #include <OpenFOAM/vectorIOField.H>
00085 #include <OpenFOAM/sphericalTensorIOField.H>
00086 #include <OpenFOAM/symmTensorIOField.H>
00087 #include <OpenFOAM/tensorIOField.H>
00088 #include <OpenFOAM/pointFields.H>
00089 
00090 #include "readFields.H"
00091 #include "fvFieldDecomposer.H"
00092 #include "pointFieldDecomposer.H"
00093 #include "lagrangianFieldDecomposer.H"
00094 
00095 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00096 
00097 int main(int argc, char *argv[])
00098 {
00099     // enable -constant
00100     timeSelector::addOptions(true, false);
00101     argList::noParallel();
00102 #   include <OpenFOAM/addRegionOption.H>
00103     argList::validOptions.insert("cellDist", "");
00104     argList::validOptions.insert("copyUniform", "");
00105     argList::validOptions.insert("fields", "");
00106     argList::validOptions.insert("filterPatches", "");
00107     argList::validOptions.insert("force", "");
00108     argList::validOptions.insert("ifRequired", "");
00109 
00110 #   include <OpenFOAM/setRootCase.H>
00111 
00112     word regionName = fvMesh::defaultRegion;
00113     word regionDir = word::null;
00114 
00115     if (args.optionFound("region"))
00116     {
00117         regionName = args.option("region");
00118         regionDir = regionName;
00119         Info<< "Decomposing mesh " << regionName << nl << endl;
00120     }
00121 
00122 
00123     bool writeCellDist           = args.optionFound("cellDist");
00124     bool copyUniform             = args.optionFound("copyUniform");
00125     bool decomposeFieldsOnly     = args.optionFound("fields");
00126     bool filterPatches           = args.optionFound("filterPatches");
00127     bool forceOverwrite          = args.optionFound("force");
00128     bool ifRequiredDecomposition = args.optionFound("ifRequired");
00129 
00130 #   include <OpenFOAM/createTime.H>
00131 
00132     // Allow -constant to override controlDict settings.
00133     if (args.optionFound("constant"))
00134     {
00135         instantList timeDirs = timeSelector::select0(runTime, args);
00136         if (runTime.timeName() != runTime.constant())
00137         {
00138             FatalErrorIn(args.executable())
00139                 << "No '" << runTime.constant() << "' time present." << endl
00140                 << "Valid times are " << runTime.times()
00141                 << exit(FatalError);
00142         }
00143     }
00144 
00145 
00146     Info<< "Time = " << runTime.timeName() << endl;
00147 
00148     // determine the existing processor count directly
00149     label nProcs = 0;
00150     while
00151     (
00152         isDir
00153         (
00154             runTime.path()
00155            /(word("processor") + name(nProcs))
00156            /runTime.constant()
00157            /regionDir
00158            /polyMesh::meshSubDir
00159         )
00160     )
00161     {
00162         ++nProcs;
00163     }
00164 
00165     // get requested numberOfSubdomains
00166     label nDomains = 0;
00167     {
00168         IOdictionary decompDict
00169         (
00170             IOobject
00171             (
00172                 "decomposeParDict",
00173                 runTime.time().system(),
00174                 regionDir,          // use region if non-standard
00175                 runTime,
00176                 IOobject::MUST_READ,
00177                 IOobject::NO_WRITE,
00178                 false
00179             )
00180         );
00181 
00182         decompDict.lookup("numberOfSubdomains") >> nDomains;
00183     }
00184 
00185     if (decomposeFieldsOnly)
00186     {
00187         // Sanity check on previously decomposed case
00188         if (nProcs != nDomains)
00189         {
00190             FatalErrorIn(args.executable())
00191                 << "Specified -fields, but the case was decomposed with "
00192                 << nProcs << " domains"
00193                 << nl
00194                 << "instead of " << nDomains
00195                 << " domains as specified in decomposeParDict"
00196                 << nl
00197                 << exit(FatalError);
00198         }
00199     }
00200     else if (nProcs)
00201     {
00202         bool procDirsProblem = true;
00203 
00204         if (ifRequiredDecomposition && nProcs == nDomains)
00205         {
00206             // we can reuse the decomposition
00207             decomposeFieldsOnly = true;
00208             procDirsProblem = false;
00209             forceOverwrite = false;
00210 
00211             Info<< "Using existing processor directories" << nl;
00212         }
00213 
00214         if (forceOverwrite)
00215         {
00216             Info<< "Removing " << nProcs
00217                 << " existing processor directories" << endl;
00218 
00219             // remove existing processor dirs
00220             // reverse order to avoid gaps if someone interrupts the process
00221             for (label procI = nProcs-1; procI >= 0; --procI)
00222             {
00223                 fileName procDir
00224                 (
00225                     runTime.path()/(word("processor") + name(procI))
00226                 );
00227 
00228                 rmDir(procDir);
00229             }
00230 
00231             procDirsProblem = false;
00232         }
00233 
00234         if (procDirsProblem)
00235         {
00236             FatalErrorIn(args.executable())
00237                 << "Case is already decomposed with " << nProcs
00238                 << " domains, use the -force option or manually" << nl
00239                 << "remove processor directories before decomposing. e.g.,"
00240                 << nl
00241                 << "    rm -rf " << runTime.path().c_str() << "/processor*"
00242                 << nl
00243                 << exit(FatalError);
00244         }
00245     }
00246 
00247     Info<< "Create mesh" << endl;
00248     domainDecomposition mesh
00249     (
00250         IOobject
00251         (
00252             regionName,
00253             runTime.timeName(),
00254             runTime
00255         )
00256     );
00257 
00258     // Decompose the mesh
00259     if (!decomposeFieldsOnly)
00260     {
00261         mesh.decomposeMesh(filterPatches);
00262 
00263         mesh.writeDecomposition();
00264 
00265         if (writeCellDist)
00266         {
00267             const labelList& procIds = mesh.cellToProc();
00268 
00269             // Write the decomposition as labelList for use with 'manual'
00270             // decomposition method.
00271             labelIOList cellDecomposition
00272             (
00273                 IOobject
00274                 (
00275                     "cellDecomposition",
00276                     mesh.facesInstance(),
00277                     mesh,
00278                     IOobject::NO_READ,
00279                     IOobject::NO_WRITE,
00280                     false
00281                 ),
00282                 procIds
00283             );
00284             cellDecomposition.write();
00285 
00286             Info<< nl << "Wrote decomposition to "
00287                 << cellDecomposition.objectPath()
00288                 << " for use in manual decomposition." << endl;
00289 
00290             // Write as volScalarField for postprocessing.
00291             volScalarField cellDist
00292             (
00293                 IOobject
00294                 (
00295                     "cellDist",
00296                     runTime.timeName(),
00297                     mesh,
00298                     IOobject::NO_READ,
00299                     IOobject::AUTO_WRITE
00300                 ),
00301                 mesh,
00302                 dimensionedScalar("cellDist", dimless, 0),
00303                 zeroGradientFvPatchScalarField::typeName
00304             );
00305 
00306             forAll(procIds, celli)
00307             {
00308                cellDist[celli] = procIds[celli];
00309             }
00310 
00311             cellDist.write();
00312 
00313             Info<< nl << "Wrote decomposition as volScalarField to "
00314                 << cellDist.name() << " for use in postprocessing."
00315                 << endl;
00316         }
00317     }
00318 
00319 
00320     // Search for list of objects for this time
00321     IOobjectList objects(mesh, runTime.timeName());
00322 
00323     // Construct the vol fields
00324     // ~~~~~~~~~~~~~~~~~~~~~~~~
00325     PtrList<volScalarField> volScalarFields;
00326     readFields(mesh, objects, volScalarFields);
00327 
00328     PtrList<volVectorField> volVectorFields;
00329     readFields(mesh, objects, volVectorFields);
00330 
00331     PtrList<volSphericalTensorField> volSphericalTensorFields;
00332     readFields(mesh, objects, volSphericalTensorFields);
00333 
00334     PtrList<volSymmTensorField> volSymmTensorFields;
00335     readFields(mesh, objects, volSymmTensorFields);
00336 
00337     PtrList<volTensorField> volTensorFields;
00338     readFields(mesh, objects, volTensorFields);
00339 
00340 
00341     // Construct the surface fields
00342     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00343     PtrList<surfaceScalarField> surfaceScalarFields;
00344     readFields(mesh, objects, surfaceScalarFields);
00345     PtrList<surfaceVectorField> surfaceVectorFields;
00346     readFields(mesh, objects, surfaceVectorFields);
00347     PtrList<surfaceSphericalTensorField> surfaceSphericalTensorFields;
00348     readFields(mesh, objects, surfaceSphericalTensorFields);
00349     PtrList<surfaceSymmTensorField> surfaceSymmTensorFields;
00350     readFields(mesh, objects, surfaceSymmTensorFields);
00351     PtrList<surfaceTensorField> surfaceTensorFields;
00352     readFields(mesh, objects, surfaceTensorFields);
00353 
00354 
00355     // Construct the point fields
00356     // ~~~~~~~~~~~~~~~~~~~~~~~~~~
00357     pointMesh pMesh(mesh);
00358 
00359     PtrList<pointScalarField> pointScalarFields;
00360     readFields(pMesh, objects, pointScalarFields);
00361 
00362     PtrList<pointVectorField> pointVectorFields;
00363     readFields(pMesh, objects, pointVectorFields);
00364 
00365     PtrList<pointSphericalTensorField> pointSphericalTensorFields;
00366     readFields(pMesh, objects, pointSphericalTensorFields);
00367 
00368     PtrList<pointSymmTensorField> pointSymmTensorFields;
00369     readFields(pMesh, objects, pointSymmTensorFields);
00370 
00371     PtrList<pointTensorField> pointTensorFields;
00372     readFields(pMesh, objects, pointTensorFields);
00373 
00374 
00375     // Construct the Lagrangian fields
00376     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00377 
00378     fileNameList cloudDirs
00379     (
00380         readDir(runTime.timePath()/cloud::prefix, fileName::DIRECTORY)
00381     );
00382 
00383     // Particles
00384     PtrList<Cloud<indexedParticle> > lagrangianPositions(cloudDirs.size());
00385     // Particles per cell
00386     PtrList< List<SLList<indexedParticle*>*> > cellParticles(cloudDirs.size());
00387 
00388     PtrList<PtrList<labelIOField> > lagrangianLabelFields(cloudDirs.size());
00389     PtrList<PtrList<scalarIOField> > lagrangianScalarFields(cloudDirs.size());
00390     PtrList<PtrList<vectorIOField> > lagrangianVectorFields(cloudDirs.size());
00391     PtrList<PtrList<sphericalTensorIOField> > lagrangianSphericalTensorFields
00392     (
00393         cloudDirs.size()
00394     );
00395     PtrList<PtrList<symmTensorIOField> > lagrangianSymmTensorFields
00396     (
00397         cloudDirs.size()
00398     );
00399     PtrList<PtrList<tensorIOField> > lagrangianTensorFields
00400     (
00401         cloudDirs.size()
00402     );
00403 
00404     label cloudI = 0;
00405 
00406     forAll(cloudDirs, i)
00407     {
00408         IOobjectList sprayObjs
00409         (
00410             mesh,
00411             runTime.timeName(),
00412             cloud::prefix/cloudDirs[i]
00413         );
00414 
00415         IOobject* positionsPtr = sprayObjs.lookup("positions");
00416 
00417         if (positionsPtr)
00418         {
00419             // Read lagrangian particles
00420             // ~~~~~~~~~~~~~~~~~~~~~~~~~
00421 
00422             Info<< "Identified lagrangian data set: " << cloudDirs[i] << endl;
00423 
00424             lagrangianPositions.set
00425             (
00426                 cloudI,
00427                 new Cloud<indexedParticle>
00428                 (
00429                     mesh,
00430                     cloudDirs[i],
00431                     false
00432                 )
00433             );
00434 
00435 
00436             // Sort particles per cell
00437             // ~~~~~~~~~~~~~~~~~~~~~~~
00438 
00439             cellParticles.set
00440             (
00441                 cloudI,
00442                 new List<SLList<indexedParticle*>*>
00443                 (
00444                     mesh.nCells(),
00445                     static_cast<SLList<indexedParticle*>*>(NULL)
00446                 )
00447             );
00448 
00449             label i = 0;
00450 
00451             forAllIter
00452             (
00453                 Cloud<indexedParticle>,
00454                 lagrangianPositions[cloudI],
00455                 iter
00456             )
00457             {
00458                 iter().index() = i++;
00459 
00460                 label celli = iter().cell();
00461 
00462                 // Check
00463                 if (celli < 0 || celli >= mesh.nCells())
00464                 {
00465                     FatalErrorIn(args.executable())
00466                         << "Illegal cell number " << celli
00467                         << " for particle with index " << iter().index()
00468                         << " at position " << iter().position() << nl
00469                         << "Cell number should be between 0 and "
00470                         << mesh.nCells()-1 << nl
00471                         << "On this mesh the particle should be in cell "
00472                         << mesh.findCell(iter().position())
00473                         << exit(FatalError);
00474                 }
00475 
00476                 if (!cellParticles[cloudI][celli])
00477                 {
00478                     cellParticles[cloudI][celli] = new SLList<indexedParticle*>
00479                     ();
00480                 }
00481 
00482                 cellParticles[cloudI][celli]->append(&iter());
00483             }
00484 
00485             // Read fields
00486             // ~~~~~~~~~~~
00487 
00488             IOobjectList lagrangianObjects
00489             (
00490                 mesh,
00491                 runTime.timeName(),
00492                 cloud::prefix/cloudDirs[cloudI]
00493             );
00494 
00495             lagrangianFieldDecomposer::readFields
00496             (
00497                 cloudI,
00498                 lagrangianObjects,
00499                 lagrangianLabelFields
00500             );
00501 
00502             lagrangianFieldDecomposer::readFields
00503             (
00504                 cloudI,
00505                 lagrangianObjects,
00506                 lagrangianScalarFields
00507             );
00508 
00509             lagrangianFieldDecomposer::readFields
00510             (
00511                 cloudI,
00512                 lagrangianObjects,
00513                 lagrangianVectorFields
00514             );
00515 
00516             lagrangianFieldDecomposer::readFields
00517             (
00518                 cloudI,
00519                 lagrangianObjects,
00520                 lagrangianSphericalTensorFields
00521             );
00522 
00523             lagrangianFieldDecomposer::readFields
00524             (
00525                 cloudI,
00526                 lagrangianObjects,
00527                 lagrangianSymmTensorFields
00528             );
00529 
00530             lagrangianFieldDecomposer::readFields
00531             (
00532                 cloudI,
00533                 lagrangianObjects,
00534                 lagrangianTensorFields
00535             );
00536 
00537             cloudI++;
00538         }
00539     }
00540 
00541     lagrangianPositions.setSize(cloudI);
00542     cellParticles.setSize(cloudI);
00543     lagrangianLabelFields.setSize(cloudI);
00544     lagrangianScalarFields.setSize(cloudI);
00545     lagrangianVectorFields.setSize(cloudI);
00546     lagrangianSphericalTensorFields.setSize(cloudI);
00547     lagrangianSymmTensorFields.setSize(cloudI);
00548     lagrangianTensorFields.setSize(cloudI);
00549 
00550 
00551     // Any uniform data to copy/link?
00552     fileName uniformDir("uniform");
00553 
00554     if (isDir(runTime.timePath()/uniformDir))
00555     {
00556         Info<< "Detected additional non-decomposed files in "
00557             << runTime.timePath()/uniformDir
00558             << endl;
00559     }
00560     else
00561     {
00562         uniformDir.clear();
00563     }
00564 
00565     Info<< endl;
00566 
00567     // split the fields over processors
00568     for (label procI = 0; procI < mesh.nProcs(); procI++)
00569     {
00570         Info<< "Processor " << procI << ": field transfer" << endl;
00571 
00572         // open the database
00573         Time processorDb
00574         (
00575             Time::controlDictName,
00576             args.rootPath(),
00577             args.caseName()/fileName(word("processor") + name(procI))
00578         );
00579 
00580         processorDb.setTime(runTime);
00581 
00582         // remove files remnants that can cause horrible problems
00583         // - mut and nut are used to mark the new turbulence models,
00584         //   their existence prevents old models from being upgraded
00585         {
00586             fileName timeDir(processorDb.path()/processorDb.timeName());
00587 
00588             rm(timeDir/"mut");
00589             rm(timeDir/"nut");
00590         }
00591 
00592         // read the mesh
00593         fvMesh procMesh
00594         (
00595             IOobject
00596             (
00597                 regionName,
00598                 processorDb.timeName(),
00599                 processorDb
00600             )
00601         );
00602 
00603         labelIOList cellProcAddressing
00604         (
00605             IOobject
00606             (
00607                 "cellProcAddressing",
00608                 procMesh.facesInstance(),
00609                 procMesh.meshSubDir,
00610                 procMesh,
00611                 IOobject::MUST_READ,
00612                 IOobject::NO_WRITE
00613             )
00614         );
00615 
00616         labelIOList boundaryProcAddressing
00617         (
00618             IOobject
00619             (
00620                 "boundaryProcAddressing",
00621                 procMesh.facesInstance(),
00622                 procMesh.meshSubDir,
00623                 procMesh,
00624                 IOobject::MUST_READ,
00625                 IOobject::NO_WRITE
00626             )
00627         );
00628 
00629         // FV fields
00630         if
00631         (
00632             volScalarFields.size()
00633          || volVectorFields.size()
00634          || volSphericalTensorFields.size()
00635          || volSymmTensorFields.size()
00636          || volTensorFields.size()
00637          || surfaceScalarFields.size()
00638          || surfaceVectorFields.size()
00639          || surfaceSphericalTensorFields.size()
00640          || surfaceSymmTensorFields.size()
00641          || surfaceTensorFields.size()
00642         )
00643         {
00644             labelIOList faceProcAddressing
00645             (
00646                 IOobject
00647                 (
00648                     "faceProcAddressing",
00649                     procMesh.facesInstance(),
00650                     procMesh.meshSubDir,
00651                     procMesh,
00652                     IOobject::MUST_READ,
00653                     IOobject::NO_WRITE
00654                 )
00655             );
00656 
00657             fvFieldDecomposer fieldDecomposer
00658             (
00659                 mesh,
00660                 procMesh,
00661                 faceProcAddressing,
00662                 cellProcAddressing,
00663                 boundaryProcAddressing
00664             );
00665 
00666             fieldDecomposer.decomposeFields(volScalarFields);
00667             fieldDecomposer.decomposeFields(volVectorFields);
00668             fieldDecomposer.decomposeFields(volSphericalTensorFields);
00669             fieldDecomposer.decomposeFields(volSymmTensorFields);
00670             fieldDecomposer.decomposeFields(volTensorFields);
00671 
00672             fieldDecomposer.decomposeFields(surfaceScalarFields);
00673             fieldDecomposer.decomposeFields(surfaceVectorFields);
00674             fieldDecomposer.decomposeFields(surfaceSphericalTensorFields);
00675             fieldDecomposer.decomposeFields(surfaceSymmTensorFields);
00676             fieldDecomposer.decomposeFields(surfaceTensorFields);
00677         }
00678 
00679 
00680         // Point fields
00681         if
00682         (
00683             pointScalarFields.size()
00684          || pointVectorFields.size()
00685          || pointSphericalTensorFields.size()
00686          || pointSymmTensorFields.size()
00687          || pointTensorFields.size()
00688         )
00689         {
00690             labelIOList pointProcAddressing
00691             (
00692                 IOobject
00693                 (
00694                     "pointProcAddressing",
00695                     procMesh.facesInstance(),
00696                     procMesh.meshSubDir,
00697                     procMesh,
00698                     IOobject::MUST_READ,
00699                     IOobject::NO_WRITE
00700                 )
00701             );
00702 
00703             pointMesh procPMesh(procMesh, true);
00704 
00705             pointFieldDecomposer fieldDecomposer
00706             (
00707                 pMesh,
00708                 procPMesh,
00709                 pointProcAddressing,
00710                 boundaryProcAddressing
00711             );
00712 
00713             fieldDecomposer.decomposeFields(pointScalarFields);
00714             fieldDecomposer.decomposeFields(pointVectorFields);
00715             fieldDecomposer.decomposeFields(pointSphericalTensorFields);
00716             fieldDecomposer.decomposeFields(pointSymmTensorFields);
00717             fieldDecomposer.decomposeFields(pointTensorFields);
00718         }
00719 
00720 
00721         // If there is lagrangian data write it out
00722         forAll(lagrangianPositions, cloudI)
00723         {
00724             if (lagrangianPositions[cloudI].size())
00725             {
00726                 lagrangianFieldDecomposer fieldDecomposer
00727                 (
00728                     mesh,
00729                     procMesh,
00730                     cellProcAddressing,
00731                     cloudDirs[cloudI],
00732                     lagrangianPositions[cloudI],
00733                     cellParticles[cloudI]
00734                 );
00735 
00736                 // Lagrangian fields
00737                 if
00738                 (
00739                     lagrangianLabelFields[cloudI].size()
00740                  || lagrangianScalarFields[cloudI].size()
00741                  || lagrangianVectorFields[cloudI].size()
00742                  || lagrangianSphericalTensorFields[cloudI].size()
00743                  || lagrangianSymmTensorFields[cloudI].size()
00744                  || lagrangianTensorFields[cloudI].size()
00745                 )
00746                 {
00747                     fieldDecomposer.decomposeFields
00748                     (
00749                         cloudDirs[cloudI],
00750                         lagrangianLabelFields[cloudI]
00751                     );
00752                     fieldDecomposer.decomposeFields
00753                     (
00754                         cloudDirs[cloudI],
00755                         lagrangianScalarFields[cloudI]
00756                     );
00757                     fieldDecomposer.decomposeFields
00758                     (
00759                         cloudDirs[cloudI],
00760                         lagrangianVectorFields[cloudI]
00761                     );
00762                     fieldDecomposer.decomposeFields
00763                     (
00764                         cloudDirs[cloudI],
00765                         lagrangianSphericalTensorFields[cloudI]
00766                     );
00767                     fieldDecomposer.decomposeFields
00768                     (
00769                         cloudDirs[cloudI],
00770                         lagrangianSymmTensorFields[cloudI]
00771                     );
00772                     fieldDecomposer.decomposeFields
00773                     (
00774                         cloudDirs[cloudI],
00775                         lagrangianTensorFields[cloudI]
00776                     );
00777                 }
00778             }
00779         }
00780 
00781 
00782         // Any non-decomposed data to copy?
00783         if (uniformDir.size())
00784         {
00785             const fileName timePath = processorDb.timePath();
00786 
00787             if (copyUniform || mesh.distributed())
00788             {
00789                 cp
00790                 (
00791                     runTime.timePath()/uniformDir,
00792                     timePath/uniformDir
00793                 );
00794             }
00795             else
00796             {
00797                 // link with relative paths
00798                 const string parentPath = string("..")/"..";
00799 
00800                 fileName currentDir(cwd());
00801                 chDir(timePath);
00802                 ln
00803                 (
00804                     parentPath/runTime.timeName()/uniformDir,
00805                     uniformDir
00806                 );
00807                 chDir(currentDir);
00808             }
00809         }
00810     }
00811 
00812 
00813     Info<< "\nEnd.\n" << endl;
00814 
00815     return 0;
00816 }
00817 
00818 
00819 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines