From 78a0b623e76f0e997e87d4d087be9b3981fefcd9 Mon Sep 17 00:00:00 2001 From: Andrew Heather <a.heather@opencfd.co.uk> Date: Thu, 21 Apr 2016 12:46:23 +0100 Subject: [PATCH] ENH: Updates to applyBoundaryLayer utility Old: - Previous versions created k and epsilon fields by default, and then processed omega and nuTilda fields if present. - Depending on the choice of turbulence model, not all of these fields would be used, and could lead to errors when running some utilities due to erroneous values. - If the omega field did not exist, it would be derived from the epsilon field, and also inherit the epsilon boundary conditions (wall functions) New: - This version will only update fields that already exist on file, i.e. will not generate any new fields, and will preserve the boundary conditions --- .../applyBoundaryLayer/applyBoundaryLayer.C | 296 ++++++++---------- 1 file changed, 123 insertions(+), 173 deletions(-) diff --git a/applications/utilities/preProcessing/applyBoundaryLayer/applyBoundaryLayer.C b/applications/utilities/preProcessing/applyBoundaryLayer/applyBoundaryLayer.C index 10d5d3b4a3..086c88f6eb 100644 --- a/applications/utilities/preProcessing/applyBoundaryLayer/applyBoundaryLayer.C +++ b/applications/utilities/preProcessing/applyBoundaryLayer/applyBoundaryLayer.C @@ -49,7 +49,7 @@ Description // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// turbulence constants - file-scope +// Turbulence constants - file-scope static const scalar Cmu(0.09); static const scalar kappa(0.41); @@ -110,75 +110,49 @@ void correctProcessorPatches(volScalarField& vf) } -template<class TurbulenceModel> -Foam::tmp<Foam::volScalarField> calcK +void blendField ( - TurbulenceModel& turbulence, - const volScalarField& mask, - const volScalarField& nut, - const volScalarField& y, - const dimensionedScalar& ybl, - const scalar Cmu, - const scalar kappa -) -{ - // Turbulence k - tmp<volScalarField> tk = turbulence->k(); - volScalarField& k = tk(); - scalar ck0 = pow025(Cmu)*kappa; - k = (1 - mask)*k + mask*sqr(nut/(ck0*min(y, ybl))); - k.rename("k"); - - // Do not correct BC - // - operation may use inconsistent fields wrt these local manipulations - //k.correctBoundaryConditions(); - correctProcessorPatches(k); - - Info<< "Writing k\n" << endl; - k.write(); - - return tk; -} - - -template<class TurbulenceModel> -Foam::tmp<Foam::volScalarField> calcEpsilon -( - TurbulenceModel& turbulence, - const volScalarField& mask, - const volScalarField& k, - const volScalarField& y, - const dimensionedScalar& ybl, - const scalar Cmu, - const scalar kappa + const word& fieldName, + const fvMesh& mesh, + const scalarField& mask, + const scalarField& boundaryLayerField ) { - // Turbulence epsilon - tmp<volScalarField> tepsilon = turbulence->epsilon(); - volScalarField& epsilon = tepsilon(); - scalar ce0 = ::pow(Cmu, 0.75)/kappa; - epsilon = (1 - mask)*epsilon + mask*ce0*k*sqrt(k)/min(y, ybl); - epsilon.max(SMALL); - epsilon.rename("epsilon"); + IOobject fieldHeader + ( + fieldName, + mesh.time().timeName(), + mesh, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false + ); - // Do not correct BC - // - operation may use inconsistent fields wrt these local manipulations - // epsilon.correctBoundaryConditions(); - correctProcessorPatches(epsilon); + if (fieldHeader.headerOk()) + { + volScalarField fld(fieldHeader, mesh); + scalarField& internalField = fld.internalField(); + internalField = (1 - mask)*internalField + mask*boundaryLayerField; + fld.max(SMALL); - Info<< "Writing epsilon\n" << endl; - epsilon.write(); + // Do not correct BC + // - operation may use inconsistent fields wrt these local + // manipulations + //fld.correctBoundaryConditions(); + correctProcessorPatches(fld); - return tepsilon; + Info<< "Writing " << fieldName << nl << endl; + fld.write(); + } } -void calcOmega +void calcOmegaField ( - const fvMesh& mesh, - const volScalarField& mask, - const volScalarField& k, - const volScalarField& epsilon + const fvMesh& mesh, + const scalarField& mask, + const scalarField& kBL, + const scalarField& epsilonBL ) { // Turbulence omega @@ -195,9 +169,10 @@ void calcOmega if (omegaHeader.headerOk()) { volScalarField omega(omegaHeader, mesh); - dimensionedScalar k0("SMALL", k.dimensions(), SMALL); + scalarField& internalField = omega.internalField(); - omega = (1 - mask)*omega + mask*epsilon/(Cmu*k + k0); + internalField = + (1 - mask)*internalField + mask*epsilonBL/(Cmu*kBL + SMALL); omega.max(SMALL); // Do not correct BC @@ -246,114 +221,79 @@ void setField } -void calcCompressible +tmp<volScalarField> calcNut ( const fvMesh& mesh, - const volScalarField& mask, - const volVectorField& U, - const volScalarField& y, - const dimensionedScalar& ybl + const volVectorField& U ) { const Time& runTime = mesh.time(); - autoPtr<fluidThermo> pThermo(fluidThermo::New(mesh)); - fluidThermo& thermo = pThermo(); - volScalarField rho(thermo.rho()); - - // Update/re-write phi - #include "compressibleCreatePhi.H" - phi.write(); - - autoPtr<compressible::turbulenceModel> turbulence + if ( - compressible::turbulenceModel::New + IOobject ( - rho, - U, - phi, - thermo - ) - ); - - // Hack to correct nut - // Note: in previous versions of the code, nut was initialised on - // construction of the turbulence model. This is no longer the - // case for the Templated Turbulence models. The call to correct - // below will evolve the turbulence model equations and update nut, - // whereas only nut update is required. Need to revisit. - turbulence->correct(); - - tmp<volScalarField> tnut = turbulence->nut(); - - volScalarField& nut = tnut(); - volScalarField S(mag(dev(symm(fvc::grad(U))))); - nut = (1 - mask)*nut + mask*sqr(kappa*min(y, ybl))*::sqrt(2)*S; - - // Do not correct BC - wall functions will 'undo' manipulation above - // by using nut from turbulence model - correctProcessorPatches(nut); - nut.write(); - - tmp<volScalarField> k = - calcK(turbulence, mask, nut, y, ybl, Cmu, kappa); - tmp<volScalarField> epsilon = - calcEpsilon(turbulence, mask, k, y, ybl, Cmu, kappa); - calcOmega(mesh, mask, k, epsilon); - setField(mesh, "nuTilda", nut); -} - - -void calcIncompressible -( - const fvMesh& mesh, - const volScalarField& mask, - const volVectorField& U, - const volScalarField& y, - const dimensionedScalar& ybl -) -{ - const Time& runTime = mesh.time(); - - // Update/re-write phi - #include "createPhi.H" - phi.write(); - - singlePhaseTransportModel laminarTransport(U, phi); - - autoPtr<incompressible::turbulenceModel> turbulence - ( - incompressible::turbulenceModel::New(U, phi, laminarTransport) - ); - - // Hack to correct nut - // Note: in previous versions of the code, nut was initialised on - // construction of the turbulence model. This is no longer the - // case for the Templated Turbulence models. The call to correct - // below will evolve the turbulence model equations and update nut, - // whereas only nut update is required. Need to revisit. - turbulence->correct(); + basicThermo::dictName, + runTime.constant(), + mesh + ).headerOk() + ) + { + // Compressible + autoPtr<fluidThermo> pThermo(fluidThermo::New(mesh)); + fluidThermo& thermo = pThermo(); + volScalarField rho(thermo.rho()); - tmp<volScalarField> tnut = turbulence->nut(); + // Update/re-write phi + #include "compressibleCreatePhi.H" + phi.write(); - // Calculate nut - reference nut is calculated by the turbulence model - // on its construction - volScalarField& nut = tnut(); + autoPtr<compressible::turbulenceModel> turbulence + ( + compressible::turbulenceModel::New + ( + rho, + U, + phi, + thermo + ) + ); + + // Hack to correct nut + // Note: in previous versions of the code, nut was initialised on + // construction of the turbulence model. This is no longer the + // case for the Templated Turbulence models. The call to correct + // below will evolve the turbulence model equations and update nut, + // whereas only nut update is required. Need to revisit. + turbulence->correct(); + + return tmp<volScalarField>(new volScalarField(turbulence->nut())); + } + else + { + // Incompressible - volScalarField S("S", mag(dev(symm(fvc::grad(U))))); - nut = (1 - mask)*nut + mask*sqr(kappa*min(y, ybl))*::sqrt(2)*S; + // Update/re-write phi + #include "createPhi.H" + phi.write(); - // Do not correct BC - wall functions will 'undo' manipulation above - // by using nut from turbulence model - correctProcessorPatches(nut); - nut.write(); + singlePhaseTransportModel laminarTransport(U, phi); - tmp<volScalarField> k = - calcK(turbulence, mask, nut, y, ybl, Cmu, kappa); - tmp<volScalarField> epsilon = - calcEpsilon(turbulence, mask, k, y, ybl, Cmu, kappa); - calcOmega(mesh, mask, k, epsilon); - setField(mesh, "nuTilda", nut); + autoPtr<incompressible::turbulenceModel> turbulence + ( + incompressible::turbulenceModel::New(U, phi, laminarTransport) + ); + + // Hack to correct nut + // Note: in previous versions of the code, nut was initialised on + // construction of the turbulence model. This is no longer the + // case for the Templated Turbulence models. The call to correct + // below will evolve the turbulence model equations and update nut, + // whereas only nut update is required. Need to revisit. + turbulence->correct(); + + return tmp<volScalarField>(new volScalarField(turbulence->nut())); + } } @@ -427,22 +367,32 @@ int main(int argc, char *argv[]) mask.correctBoundaryConditions(); Udash.correctBoundaryConditions(); - if - ( - IOobject - ( - basicThermo::dictName, - runTime.constant(), - mesh - ).headerOk() - ) - { - calcCompressible(mesh, mask, Udash, y, ybl); - } - else - { - calcIncompressible(mesh, mask, Udash, y, ybl); - } + // Retrieve nut from turbulence model + volScalarField nut(calcNut(mesh, Udash)); + + // Blend nut using boundary layer profile + volScalarField S("S", mag(dev(symm(fvc::grad(Udash))))); + nut = (1 - mask)*nut + mask*sqr(kappa*min(y, ybl))*::sqrt(2)*S; + + // Do not correct BC - wall functions will 'undo' manipulation above + // by using nut from turbulence model + correctProcessorPatches(nut); + nut.write(); + + // Boundary layer turbulence kinetic energy + scalar ck0 = pow025(Cmu)*kappa; + scalarField kBL(sqr(nut/(ck0*min(y, ybl)))); + + // Boundary layer turbulence dissipation + scalar ce0 = ::pow(Cmu, 0.75)/kappa; + scalarField epsilonBL(ce0*kBL*sqrt(kBL)/min(y, ybl)); + + // Process fields if they are present + blendField("k", mesh, mask, kBL); + blendField("epsilon", mesh, mask, epsilonBL); + calcOmegaField(mesh, mask, kBL, epsilonBL); + setField(mesh, "nuTilda", nut); + // Copy internal field Udash into U before writing Info<< "Writing U\n" << endl; -- GitLab