/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2014-2022 PCOpt/NTUA Copyright (C) 2014-2022 FOSS GP ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . Class Foam::incompressibleAdjoint::adjointRASModels::adjointkOmegaSST Description Continuous adjoint to the kOmegaSST turbulence model for incompressible flows. Reference: \verbatim The code is based on the following reference, with a number of changes in the numerical implementation Kavvadias, I., Papoutsis-Kiachagias, E., Dimitrakopoulos, G., & Giannakoglou, K. (2014). The continuous adjoint approach to the k–ω SST turbulence model with applications in shape optimization Engineering Optimization, 47(11), 1523-1542. https://doi.org/10.1080/0305215X.2014.979816 \endverbatim SourceFiles adjointkOmegaSST.C \*---------------------------------------------------------------------------*/ #ifndef Foam_adjointkOmegaSST_H #define Foam_adjointkOmegaSST_H #include "adjointRASModel.H" #include "wallDist.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { namespace incompressibleAdjoint { namespace adjointRASModels { /*---------------------------------------------------------------------------*\ Class adjointkOmegaSST Declaration \*---------------------------------------------------------------------------*/ class adjointkOmegaSST : public adjointRASModel { // Private Member Functions //- No copy construct adjointkOmegaSST(const adjointkOmegaSST&) = delete; //- No copy assignment void operator=(const adjointkOmegaSST&) = delete; protected: // Protected data // Primal Model coefficients dimensionedScalar kappa_; dimensionedScalar alphaK1_; dimensionedScalar alphaK2_; dimensionedScalar alphaOmega1_; dimensionedScalar alphaOmega2_; dimensionedScalar gamma1_; dimensionedScalar gamma2_; dimensionedScalar beta1_; dimensionedScalar beta2_; dimensionedScalar betaStar_; dimensionedScalar a1_; dimensionedScalar b1_; dimensionedScalar c1_; //- Flag to include the F3 term Switch F3_; // Fields // Primal Fields //- Wall distance // Note: reference to the distance known by the primal model const volScalarField& y_; //- Cached primal gradient fields volTensorField gradU_; volVectorField gradOmega_; volVectorField gradK_; //- Primal cached fields involved in the solution of the // adjoint equations // Cached to reduce the computational cost volScalarField S2_; volScalarField S_; volScalarField GbyNu0_; volScalarField CDkOmega_; volScalarField CDkOmegaPlus_; volScalarField F1_; volScalarField F2_; // Model Field coefficients volScalarField alphaK_; volScalarField alphaOmega_; volScalarField beta_; volScalarField gamma_; // Switch fields // Switch fields for the differentiation of F1 volScalarField case_1_F1_; volScalarField case_2_F1_; volScalarField case_3_F1_; volScalarField case_4_F1_; //- Switch fields for the production in the k Eqn volScalarField case_1_Pk_; volScalarField case_2_Pk_; volScalarField case_3_Pk_; // Switch fields for the differentiation of nut // Holds also for the differentiation of the second branch of // GbyNu volScalarField case_1_nut_; volScalarField case_2_nut_; volScalarField case_3_nut_; // Switch fields for GPrime volScalarField case_1_GPrime_; volScalarField case_2_GPrime_; // Zero first cell field and IDs // Since the omega equation is a two-zonal one, some // of the terms in the adjoint equations need to ba canceled // at the cells next to omegaWallFunction BCs labelList firstCellIDs_; volScalarField zeroFirstCell_; // Turbulence model multipliers //- Nut Jacobian w.r.t. omega volScalarField dnut_domega_; //- Nut Jacobian w.r.t. k volScalarField dnut_dk_; //- Diffusivity of the omega equation volScalarField DOmegaEff_; //- Diffusivity of the k equation volScalarField DkEff_; // Protected Member Functions // Primal functions virtual tmp F1() const; virtual tmp F2() const; virtual tmp GbyNu ( const volScalarField& GbyNu0, const volScalarField& F2, const volScalarField& S2 ) const; //- Return G/nu virtual tmp GbyNu ( const volScalarField::Internal& GbyNu0, const volScalarField::Internal& F2, const volScalarField::Internal& S2 ) const; tmp blend ( const volScalarField& F1, const dimensionedScalar& psi1, const dimensionedScalar& psi2 ) const { return F1*(psi1 - psi2) + psi2; } tmp blend ( const volScalarField::Internal& F1, const dimensionedScalar& psi1, const dimensionedScalar& psi2 ) const { return F1*(psi1 - psi2) + psi2; } tmp alphaK(const volScalarField& F1) const { return blend(F1, alphaK1_, alphaK2_); } tmp alphaOmega(const volScalarField& F1) const { return blend(F1, alphaOmega1_, alphaOmega2_); } tmp beta ( const volScalarField::Internal& F1 ) const { return tmp::New ( IOobject::scopedName(this->type(), "beta"), blend(F1, beta1_, beta2_) ); } tmp beta ( const volScalarField& F1 ) const { return tmp::New ( IOobject::scopedName(this->type(), "beta"), blend(F1, beta1_, beta2_) ); } tmp gamma ( const volScalarField::Internal& F1 ) const { return tmp::New ( IOobject::scopedName(this->type(), "gamma"), blend(F1, gamma1_, gamma2_) ); } tmp gamma ( const volScalarField& F1 ) const { return tmp::New ( IOobject::scopedName(this->type(), "gamma"), blend(F1, gamma1_, gamma2_) ); } tmp zeroFirstCell(); // References to the primal turbulence model variables inline const volScalarField& k() const { return primalVars_.RASModelVariables()().TMVar1(); } inline volScalarField& k() { return primalVars_.RASModelVariables()().TMVar1(); } inline const volScalarField& omega() const { return primalVars_.RASModelVariables()().TMVar2(); } inline volScalarField& omega() { return primalVars_.RASModelVariables()().TMVar2(); } inline const volScalarField& nutRef() const { return primalVars_.RASModelVariables()().nutRef(); } inline volScalarField& nutRef() { return primalVars_.RASModelVariables()().nutRef(); } // Adjoint related protected member functions //- Derivative of the primal equations wrt nut tmp dR_dnut(); //- Nut Jacobian wrt omega tmp dnut_domega ( const volScalarField& F2, const volScalarField& S, const volScalarField& case_1_nut, const volScalarField& case_2_nut, const volScalarField& case_3_nut ) const; //- Nut Jacobian wrt k tmp dnut_dk ( const volScalarField& F2, const volScalarField& S, const volScalarField& case_2_nut ) const; //- F2 Jacobian wrt omega tmp dF2_domega ( const volScalarField& F2, const volScalarField& case_2_nut, const volScalarField& case_3_nut ) const; //- F2 Jacobian wrt k tmp dF2_dk ( const volScalarField& F2, const volScalarField& case_2_nut ) const; //- GbyNu Jacobian wrt omega tmp dGPrime_domega() const; //- GbyNu Jacobian wrt k tmp dGPrime_dk() const; //- Derivative of the primal equations wrt F1 tmp dR_dF1() const; //- F1 Jacobian wrt omega (no contributions from grad(omega)) tmp dF1_domega(const volScalarField& arg1) const; //- F1 Jacobian wrt grad(omega) tmp dF1_dGradOmega ( const volScalarField& arg1 ) const; //- Source to waEqn from the differentiation of F1 tmp waEqnSourceFromF1() const; //- Source to waEqn from the differentiation of CDkOmega tmp waEqnSourceFromCDkOmega() const; //- F1 Jacobian wrt k (no contributions from grad(k)) tmp dF1_dk(const volScalarField& arg1) const; //- F1 Jacobian wrt grad(k) tmp dF1_dGradK(const volScalarField& arg1) const; //- Source to kaEqn from the differentiation of F1 tmp kaEqnSourceFromF1() const; //- Source to kaEqn from the differentiation of CDkOmega tmp kaEqnSourceFromCDkOmega() const; //- Differentiation of the turbulence model diffusion coefficients tmp coeffsDifferentiation ( const volScalarField& primalField, const volScalarField& adjointField, const word& schemeName ) const; //- Term multiplying dnut/db, coming from the turbulence model tmp dNutdbMult ( const volScalarField& primalField, const volScalarField& adjointField, const volScalarField& coeffField, const volScalarField& bcField, const word& schemeName ) const; //- Term multiplying dnut/db, coming from the momentum equations tmp dNutdbMult ( const volVectorField& primalField, const volVectorField& adjointField, const volScalarField& bcField, const word& schemeName ) const; // Functions computing the adjoint mean flow source //- Contributions from the turbulence model convection terms tmp convectionMeanFlowSource ( const volScalarField& primalField, const volScalarField& adjointField ) const; //- Contributions from the G tmp GMeanFlowSource ( tmp& GbyNuMult ) const; //- Contributions from the divU tmp divUMeanFlowSource ( tmp& divUMult ) const; //- Contributions from nut(U), in the diffusion coefficients //- of the turbulence model tmp diffusionNutMeanFlowMult ( const volScalarField& primalField, const volScalarField& adjointField, const volScalarField& coeffField ) const; //- Contributions from nut(U) tmp nutMeanFlowSource ( tmp& mult, const volScalarField& F2, const volScalarField& S, const volScalarField& case_1_nut, const volTensorField& gradU ) const; //- Contributions from the differentiation of k existing in //- nutkWallFunction. // This could also be implemented in kaqRWallFunction but all // the fields required for the computation already exist here, // hence the code complexity is reduced void addWallFunctionTerms ( fvScalarMatrix& kaEqn, const volScalarField& dR_dnut ); // References to the adjoint turbulence model fields inline volScalarField& ka() { return adjointTMVariable1Ptr_(); }; inline const volScalarField& ka() const { return adjointTMVariable1Ptr_(); }; inline volScalarField& wa() { return adjointTMVariable2Ptr_(); }; inline const volScalarField& wa() const { return adjointTMVariable2Ptr_(); }; //- Update of the primal cached fields void updatePrimalRelatedFields(); //- Return the requested interpolation scheme if it exists, //- otherwise return a reverseLinear scheme template tmp> interpolationScheme ( const word& schemeName ) const; //- Return the interpolation scheme used by the primal convection //- term of the equation corresponding to the argument tmp> convectionScheme ( const word& varName ) const; public: //- Runtime type information TypeName("adjointkOmegaSST"); // Constructors //- Construct from components adjointkOmegaSST ( incompressibleVars& primalVars, incompressibleAdjointMeanFlowVars& adjointVars, objectiveManager& objManager, const word& adjointTurbulenceModelName = adjointTurbulenceModel::typeName, const word& modelName = typeName ); //- Destructor virtual ~adjointkOmegaSST() = default; // Member Functions //- Return the effective diffusivity for k tmp DkEff(const volScalarField& F1) const { return tmp ( new volScalarField("DkEff", alphaK(F1)*this->nut() + this->nu()) ); } //- Return the effective diffusivity for omega tmp DomegaEff(const volScalarField& F1) const { return tmp ( new volScalarField ( "DomegaEff", alphaOmega(F1)*this->nut() + this->nu() ) ); } virtual tmp devReff() const; virtual tmp devReff(const volVectorField& U) const; //- Return the transpose part of the adjoint momentum stresses virtual tmp divDevReff(volVectorField& U) const; //- Non-conservative part of the terms added to the mean flow equations virtual tmp nonConservativeMomentumSource() const; //- Source term added to the adjoint mean flow due to the //- differentiation of the turbulence model virtual tmp adjointMeanFlowSource(); //- Jacobian of nut wrt to k // Needs to be implemented for objectives related to nut, defined in // the internal field virtual tmp nutJacobianTMVar1() const; //- Jacobian of nut wrt to omega // Needs to be implemented for objectives related to nut, defined in // the internal field virtual tmp nutJacobianTMVar2() const; //- Jacobian of nut wrt the flow velocity // Assumes we want to get contributions of mult*d(nut)/dU // Since the dependency of nut to U is usually through a differential // operator, the term multiplying d(nut)/dU is passed as an argument // to this function; the latter should then compute the // contribution of the afforementioned term to the adjoint mean flow // equations virtual tmp nutJacobianU ( tmp& dNutdUMult ) const; //- Diffusion coeff at the boundary for k virtual tmp diffusionCoeffVar1(label patchI) const; //- Diffusion coeff at the boundary for omega virtual tmp diffusionCoeffVar2(label patchI) const; virtual const boundaryVectorField& adjointMomentumBCSource() const; //- Sensitivity derivative contributions when using the (E)SI approach virtual const boundaryVectorField& wallShapeSensitivities(); virtual const boundaryVectorField& wallFloCoSensitivities(); //- Contributions to the adjoint eikonal equation (zero for now) virtual tmp distanceSensitivities(); //- Sensitivity derivative contributions when using the FI approach virtual tmp FISensitivityTerm(); virtual tmp topologySensitivities ( const word& designVarsName ) const; //- Nullify all adjoint turbulence model fields and their old times virtual void nullify(); //- Solve the adjoint turbulence equations virtual void correct(); //- Read adjointRASProperties dictionary virtual bool read(); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace adjointRASModels } // End namespace incompressibleAdjoint } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository #include "adjointkOmegaSSTTemplates.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* //