)+∂xj∂ρˉuiuj=∂xj∂σij+∂xj∂(−ρˉui′uj′)其中公式中的粘性应力
σij=τij−pδij=2μ(Sij−31Skkδij)−pδij。
雷诺应力
Γij=−ρˉui′uj′,
根据 Boussinesq 假设:Γij−31Γkkδij=2μt(Sij−31Skkδij),这里简化成了不可压版本:Γij=2μt(Sij−31Skkδij)。
这个 turbulence->divDevRhoReff(U)
就是公式中的粘性应力和雷诺应力移到方程左边了。
下面详细解释了这个过程:
template<class BasicTurbulenceModel> Foam::tmp<Foam::fvVectorMatrix> Foam::linearViscousStress<BasicTurbulenceModel>::divDevRhoReff ( volVectorField& U ) const { return ( - fvc::div((this->alpha_*this->rho_*this->nuEff())*dev2(T(fvc::grad(U)))) - fvm::laplacian(this->alpha_*this->rho_*this->nuEff(), U) ); }
|
代码中表示的公式是
−∇⋅(ρ∗νeff((∇⊗u)T−32tr(∇⊗u)T))−∇⋅(ρ∗νeff∇⊗u)=−∇⋅(ρ∗νeff(∇⊗u+(∇⊗u)T)−32ρ∗νefftr(∇⊗u)T)=−∇⋅(ρ∗νeff(∇⊗u+(∇⊗u)T)−32ρ∗νeff(∇⋅u)I)=−∇⋅(2ρ∗νeffSij−32ρ∗νeffSkkδij)=−∇⋅(2ρ∗(ν+νt)Sij−32ρ∗(ν+νt)Skkδij)=−∇⋅(τij+Γij)
∇⊗u=⎝⎜⎜⎜⎜⎜⎛∂x∂u∂x∂v∂x∂w∂y∂u∂y∂v∂y∂w∂z∂u∂z∂v∂z∂w⎠⎟⎟⎟⎟⎟⎞
(∇⊗u)T=⎝⎜⎜⎜⎜⎛∂x∂u∂y∂u∂z∂u∂x∂v∂y∂v∂z∂v∂x∂w∂y∂w∂z∂w⎠⎟⎟⎟⎟⎞
tr(∇⊗u)=tr((∇⊗u)T)=∂xk∂uk=∇⋅u=tr(Sij)
strain rateSij :
Sij=21(∂xj∂ui+∂xi∂uj)=21(∇⊗u+(∇⊗u)T)
Sij=⎝⎜⎜⎜⎜⎜⎛∂x∂uS21S3121(∂y∂u+∂x∂v)∂y∂vS3221(∂z∂u+∂x∂w)21(∂z∂v+∂y∂w)∂z∂w⎠⎟⎟⎟⎟⎟⎞
Sij 是对称矩阵,S12=S21, S13=S31, S23=S32。
tr(Sij)=Skk=∂xk∂uk=∇⋅u
Sij 在代码中是:symm(fvc::grad(U))
,其中 symm(tensor) = 1/2*(tensor + T(tensor))
。
deformation rate tensorDij:
Dij=Sij−31tr(Sij)=⎝⎛S11−31(S11+S22+S33)S21S31S12S22−31(S11+S22+S33)S32S13S23S33−31(S11+S22+S33)⎠⎞=Sij−31∇⋅uδij
Dij 在代码中是:dev(symm(fvc::grad(U)))
,也就是 dev(S_{ij})
。
template <class Cmpt> inline Tensor <Cmpt> dev(const Tensor <Cmpt >& t) { return t - SphericalTensor <Cmpt >::oneThirdsI*tr(t); }
template <class Cmpt> inline Tensor <Cmpt> dev2(const Tensor <Cmpt >& t) { return t - SphericalTensor <Cmpt >::twoThirdsI*tr(t); }
|
参考文献:
Tobias Holzmann. Mathematics, Numerics, Derivations and OpenFOAM®, Holzmann CFD,
URL www.holzmann-cfd.de, DOI: 10.13140/RG.2.2.27193.36960.
以下公式适用于可压缩流动:
Cauchy stress tensorσ=σ=−pI+[σ−31tr(σ)I]
shear−rate tensorτ=σ−31tr(σ)I=σdev
即:σ=−pI+τ
Reynolds-Stress tensor
σt=−ρˉui′uj′
Boussinesq 假设:
σt−31tr(σt)=2μtDˉ−32tr(Dˉ)I
这里的Dˉ 是变形速率张量,deformation rate tensor,一般也称为Sij。
tr(σt)=tr(−ρˉui′uj′)=(−ρˉu′u′)+(−ρˉv′v′)+(−ρˉw′w′)=−2ρˉIk
故雷诺应力可以写为:
σt=2μtDˉ−32tr(Dˉ)I+31tr(σt)=2μtDˉ−32tr(Dˉ)I−32ρˉIk
tr(σt)=tr(τt−32ρˉIk)=−2ρˉIktr(σt)=tr(2μtDˉ−32μttr(D)I−32ρˉIk)=−2ρˉIk
对于 RANS
速度输运方程:
∂t∂(ρˉui)+∂xj∂ρˉuiuj=∂xj∂σij+∂xj∂(Γij)
这里的Γij 对应上文中的σt。
最后变形为:
∂t∂(ρˉui)+∂xj∂ρˉuiuj=−∂xi∂p−∂xj∂(32ρˉδijk)+∂xj∂[2(μ+μt)(Sij−∂xk∂ukδij)]
OF 速度输运方程代码里边并没有包含k 这一项,因此代码里的p 并不是真正的压力,而是p+32ρk。Page 76 in the book of Tobias.
对于 LES
速度输运方程:
∂t∂(ρˉui)+∂xj∂ρˉuiuj=∂xj∂σij−∂xj∂(Γij)
Boussinesq 假设:
Γij−31Γkkδij=−2μt(Sij−31Skkδij)
LES 中有tr(Γij)=Γkk=2ρˉk
因此:
Γij=−2μt(Sij−31Skkδij)−32ρˉkδij
速度输运方程可以变形为:
∂t∂(ρˉui)+∂xj∂ρˉuiuj=−∂xi∂p+∂xj∂(32ρˉδijk)+∂xj∂[2(μ+μt)(Sij−∂xk∂ukδij)]
那么按照 Tobias 的说法,OF 速度输运方程代码里边并没有包含k 这一项,因此代码里的p 并不是真正的压力,而是p−32ρk?
按照上边的观点,OF代码中的 p 其实并不是真实的压力,那么它怎么能用于气体状态方程呢?这个问题是论坛里网友提出来的:cfd-online。
其实最简单的就是把缺失的那个 k 补上,为什么大家不这么做呢?看看网上的讨论。
https://www.cfd-online.com/Forums/openfoam-solving/58214-calculating-divdevreff.html
一些矢量和张量的操作
LES 中经常出现的∣S~∣=2SijSij,用代码表示是:
volSymmTensorField Sij = symm(fvc::grad(U)); volScalarField magSij = sqrt(2*(Sij && Sij));
|
这里的 &&
的操作是缩并,也叫双内积,两个二阶张量的缩并是一个标量。
template<class Cmpt> inline Cmpt operator&&(const SymmTensor<Cmpt>& st1, const SymmTensor<Cmpt>& st2) { return ( st1.xx()*st2.xx() + 2*st1.xy()*st2.xy() + 2*st1.xz()*st2.xz() + st1.yy()*st2.yy() + 2*st1.yz()*st2.yz() + st1.zz()*st2.zz() ); }
|
&
是内积,也叫数量积,也叫点乘,两个矢量的内积是一个标量。
^
是叉乘,两个矢量的叉乘,仍旧是一个矢量。在三维几何中,向量a和向量b的叉乘结果是一个向量,更为熟知的叫法是法向量,该向量垂直于a和b向量构成的平面。
template<class Cmpt> inline Vector<Cmpt> operator^(const Vector<Cmpt>& v1, const Vector<Cmpt>& v2) { return Vector<Cmpt> ( (v1.y()*v2.z() - v1.z()*v2.y()), (v1.z()*v2.x() - v1.x()*v2.z()), (v1.x()*v2.y() - v1.y()*v2.x()) ); }
|
外积 a*b
,也叫量积(tensor-product),两个矢量可以形成一个二阶张量。
template<class Cmpt> inline typename outerProduct<Vector<Cmpt>, Vector<Cmpt>>::type operator*(const Vector<Cmpt>& v1, const Vector<Cmpt>& v2) { return Tensor<Cmpt> ( v1.x()*v2.x(), v1.x()*v2.y(), v1.x()*v2.z(), v1.y()*v2.x(), v1.y()*v2.y(), v1.y()*v2.z(), v1.z()*v2.x(), v1.z()*v2.y(), v1.z()*v2.z() ); }
|
sqr(U)=uiuj
这个全局函数没看懂什么意思:
template<class Cmpt> inline Vector<Cmpt> perpendicular(const Vector<Cmpt>& v) { Vector<Cmpt> u(Zero); u[findMin(cmptMag(v))] = 1; return u ^ v; }
|
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 OpenFOAM 成长之路! 您的肯定会给我更大动力~