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

applyWallFunctionBoundaryConditions.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-2007 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     applyWallFunctionBounaryConditions
00026 
00027 Description
00028     Updates OpenFOAM RAS cases to use the new (v1.6) wall function framework
00029 
00030     Attempts to determine whether case is compressible or incompressible, or
00031     can be supplied with -compressible command line argument
00032 
00033 Usage
00034     - applyWallFunctionBoundaryConditions [OPTION]
00035 
00036     @param -compressible
00037     Operate in compressible mode.
00038 
00039     @param -noZero \n
00040     Ignore timestep 0.
00041 
00042     @param -constant \n
00043     Include the constant directory.
00044 
00045     @param -time <time>\n
00046     Apply only to specific time.
00047 
00048     @param -latestTime \n
00049     Only apply to latest time step.
00050 
00051     @param -case <dir> \n
00052     Specify the case directory
00053 
00054     @param -parallel \n
00055     Run the case in parallel
00056 
00057     @param -help \n
00058     Display short usage message
00059 
00060     @param -doc \n
00061     Display Doxygen documentation page
00062 
00063     @param -srcDoc \n
00064     Display source code
00065 
00066 \*---------------------------------------------------------------------------*/
00067 
00068 #include <OpenFOAM/argList.H>
00069 #include <finiteVolume/fvMesh.H>
00070 #include <OpenFOAM/Time.H>
00071 #include <finiteVolume/volFields.H>
00072 #include <finiteVolume/surfaceFields.H>
00073 
00074 #include <OpenFOAM/wallPolyPatch.H>
00075 
00076 #include <incompressibleRASModels/epsilonWallFunctionFvPatchScalarField.H>
00077 #include <incompressibleRASModels/kqRWallFunctionFvPatchField.H>
00078 #include <incompressibleRASModels/nutWallFunctionFvPatchScalarField.H>
00079 #include <incompressibleRASModels/omegaWallFunctionFvPatchScalarField.H>
00080 
00081 #include <compressibleRASModels/epsilonWallFunctionFvPatchScalarField.H>
00082 #include <compressibleRASModels/kqRWallFunctionFvPatchField.H>
00083 #include <compressibleRASModels/mutWallFunctionFvPatchScalarField.H>
00084 #include <compressibleRASModels/omegaWallFunctionFvPatchScalarField.H>
00085 
00086 using namespace Foam;
00087 
00088 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00089 
00090 bool caseIsCompressible(const fvMesh& mesh)
00091 {
00092     // Attempt flux field
00093     IOobject phiHeader
00094     (
00095         "phi",
00096         mesh.time().timeName(),
00097         mesh,
00098         IOobject::MUST_READ,
00099         IOobject::NO_WRITE
00100     );
00101 
00102     if (phiHeader.headerOk())
00103     {
00104         surfaceScalarField phi(phiHeader, mesh);
00105         if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
00106         {
00107             return true;
00108         }
00109     }
00110 
00111     // Attempt density field
00112     IOobject rhoHeader
00113     (
00114         "rho",
00115         mesh.time().timeName(),
00116         mesh,
00117         IOobject::MUST_READ,
00118         IOobject::NO_WRITE
00119     );
00120 
00121     if (rhoHeader.headerOk())
00122     {
00123         volScalarField rho(rhoHeader, mesh);
00124         if (rho.dimensions() == dimDensity)
00125         {
00126             return true;
00127         }
00128     }
00129 
00130     // Attempt pressure field
00131     IOobject pHeader
00132     (
00133         "p",
00134         mesh.time().timeName(),
00135         mesh,
00136         IOobject::MUST_READ,
00137         IOobject::NO_WRITE
00138     );
00139 
00140     if (pHeader.headerOk())
00141     {
00142         volScalarField p(pHeader, mesh);
00143         if (p.dimensions() == dimMass/sqr(dimTime)/dimLength)
00144         {
00145             return true;
00146         }
00147     }
00148 
00149     // If none of the above are true, assume that the case is incompressible
00150     return false;
00151 }
00152 
00153 
00154 void createVolScalarField
00155 (
00156     const fvMesh& mesh,
00157     const word& fieldName,
00158     const dimensionSet& dims
00159 )
00160 {
00161     IOobject fieldHeader
00162     (
00163         fieldName,
00164         mesh.time().timeName(),
00165         mesh,
00166         IOobject::MUST_READ,
00167         IOobject::NO_WRITE
00168     );
00169 
00170     if (!fieldHeader.headerOk())
00171     {
00172         Info<< "Creating field " << fieldName << nl << endl;
00173 
00174         volScalarField field
00175         (
00176             IOobject
00177             (
00178                 fieldName,
00179                 mesh.time().timeName(),
00180                 mesh,
00181                 IOobject::NO_READ,
00182                 IOobject::NO_WRITE
00183             ),
00184             mesh,
00185             dimensionedScalar("zero", dims, 0.0)
00186         );
00187 
00188         field.write();
00189     }
00190 }
00191 
00192 
00193 void replaceBoundaryType
00194 (
00195     const fvMesh& mesh,
00196     const word& fieldName,
00197     const word& boundaryType,
00198     const string& boundaryValue
00199 )
00200 {
00201     IOobject header
00202     (
00203         fieldName,
00204         mesh.time().timeName(),
00205         mesh,
00206         IOobject::MUST_READ,
00207         IOobject::NO_WRITE
00208     );
00209 
00210     if (!header.headerOk())
00211     {
00212         return;
00213     }
00214 
00215     Info<< "Updating boundary types for field " << header.name() << endl;
00216 
00217     const word oldTypeName = IOdictionary::typeName;
00218     const_cast<word&>(IOdictionary::typeName) = word::null;
00219 
00220     IOdictionary dict(header);
00221 
00222     const_cast<word&>(IOdictionary::typeName) = oldTypeName;
00223     const_cast<word&>(dict.type()) = dict.headerClassName();
00224 
00225     // Make a backup of the old field
00226     word backupName(dict.name() + ".old");
00227     Info<< "    copying " << dict.name() << " to "
00228         << backupName << endl;
00229     IOdictionary dictOld = dict;
00230     dictOld.rename(backupName);
00231     dictOld.regIOobject::write();
00232 
00233     // Loop through boundary patches and update
00234     const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
00235     dictionary& boundaryDict = dict.subDict("boundaryField");
00236     forAll(bMesh, patchI)
00237     {
00238         if (isA<wallPolyPatch>(bMesh[patchI]))
00239         {
00240             word patchName = bMesh[patchI].name();
00241             dictionary& oldPatch = boundaryDict.subDict(patchName);
00242 
00243             dictionary newPatch(dictionary::null);
00244             newPatch.add("type", boundaryType);
00245             newPatch.add("value", ("uniform " + boundaryValue).c_str());
00246 
00247             oldPatch = newPatch;
00248         }
00249     }
00250 
00251     Info<< "    writing updated " << dict.name() << nl << endl;
00252     dict.regIOobject::write();
00253 }
00254 
00255 
00256 void updateCompressibleCase(const fvMesh& mesh)
00257 {
00258     Info<< "Case treated as compressible" << nl << endl;
00259     createVolScalarField
00260     (
00261         mesh,
00262         "mut",
00263         dimArea/dimTime*dimDensity
00264     );
00265     replaceBoundaryType
00266     (
00267         mesh,
00268         "mut",
00269         compressible::RASModels::mutWallFunctionFvPatchScalarField::typeName,
00270         "0"
00271     );
00272     replaceBoundaryType
00273     (
00274         mesh,
00275         "epsilon",
00276         compressible::RASModels::epsilonWallFunctionFvPatchScalarField::
00277             typeName,
00278         "0"
00279     );
00280     replaceBoundaryType
00281     (
00282         mesh,
00283         "omega",
00284         compressible::RASModels::omegaWallFunctionFvPatchScalarField::typeName,
00285         "0"
00286     );
00287     replaceBoundaryType
00288     (
00289         mesh,
00290         "k",
00291         compressible::RASModels::kqRWallFunctionFvPatchField<scalar>::typeName,
00292         "0"
00293     );
00294     replaceBoundaryType
00295     (
00296         mesh,
00297         "q",
00298         compressible::RASModels::kqRWallFunctionFvPatchField<scalar>::typeName,
00299         "0"
00300     );
00301     replaceBoundaryType
00302     (
00303         mesh,
00304         "R",
00305         compressible::RASModels::kqRWallFunctionFvPatchField<symmTensor>::
00306             typeName,
00307         "(0 0 0 0 0 0)"
00308     );
00309 }
00310 
00311 
00312 void updateIncompressibleCase(const fvMesh& mesh)
00313 {
00314     Info<< "Case treated as incompressible" << nl << endl;
00315     createVolScalarField(mesh, "nut", dimArea/dimTime);
00316 
00317     replaceBoundaryType
00318     (
00319         mesh,
00320         "nut",
00321         incompressible::RASModels::nutWallFunctionFvPatchScalarField::typeName,
00322         "0"
00323     );
00324     replaceBoundaryType
00325     (
00326         mesh,
00327         "epsilon",
00328         incompressible::RASModels::epsilonWallFunctionFvPatchScalarField::
00329             typeName,
00330         "0"
00331     );
00332     replaceBoundaryType
00333     (
00334         mesh,
00335         "omega",
00336         incompressible::RASModels::omegaWallFunctionFvPatchScalarField::
00337             typeName,
00338         "0"
00339     );
00340     replaceBoundaryType
00341     (
00342         mesh,
00343         "k",
00344         incompressible::RASModels::kqRWallFunctionFvPatchField<scalar>::
00345             typeName,
00346         "0"
00347     );
00348     replaceBoundaryType
00349     (
00350         mesh,
00351         "q",
00352         incompressible::RASModels::kqRWallFunctionFvPatchField<scalar>::
00353             typeName,
00354         "0"
00355     );
00356     replaceBoundaryType
00357     (
00358         mesh,
00359         "R",
00360         incompressible::RASModels::kqRWallFunctionFvPatchField<symmTensor>::
00361             typeName,
00362         "(0 0 0 0 0 0)"
00363     );
00364 }
00365 
00366 
00367 int main(int argc, char *argv[])
00368 {
00369     #include <OpenFOAM/addTimeOptions.H>
00370     argList::validOptions.insert("compressible", "");
00371 
00372     #include <OpenFOAM/setRootCase.H>
00373     #include <OpenFOAM/createTime.H>
00374     #include <OpenFOAM/createMesh.H>
00375 
00376     bool compressible = args.optionFound("compressible");
00377 
00378     Info<< "Updating turbulence fields to operate using new run time "
00379         << "selectable" << nl << "wall functions"
00380         << nl << endl;
00381 
00382     if (compressible || caseIsCompressible(mesh))
00383     {
00384         updateCompressibleCase(mesh);
00385     }
00386     else
00387     {
00388         updateIncompressibleCase(mesh);
00389     }
00390 
00391     Info<< "End\n" << endl;
00392 
00393     return 0;
00394 }
00395 
00396 
00397 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines