从数学公式到 C++ 代码
本文下标 p 表示 parcel,g 表示 gas。
dispersion 传统 RANS 框架下的公式粒子速度方程:
d d t x p = u p d d t u p = C D τ p R e p 24 ( u g − u p ) = C D τ p R e p 24 v r e l \begin{aligned} \frac{d}{dt} \mathbf{x}_{\mathbf{p}} &=\mathbf{u}_{\mathbf{p}} \\ \frac{d}{d t} \mathbf{u}_{\mathbf{p}} &=\frac{C_{D}}{\tau_{p}} \frac{R e_{p}}{24}\left(\mathbf{u}_{\mathbf{g}}-\mathbf{u}_{\mathbf{p}}\right)=\frac{C_{D}}{\tau_{p}} \frac{R e_{p}}{24} \mathbf{v}_{\mathbf{r e l}} \end{aligned} d t d x p d t d u p = u p = τ p C D 2 4 R e p ( u g − u p ) = τ p C D 2 4 R e p v r e l
其中的未知量C D C_D C D ,v r e l \mathbf{v}_{\mathbf{r e l}} v r e l ,τ p \tau_{p} τ p 计算如下:
C D = 24 R e p ( 1 + 1 6 R e p 2 / 3 ) R e p < 1000 C D = 0.424 R e p ⩾ 1000 \begin{array}{ll} C_D=\dfrac{24}{Re_p}\left(1+\dfrac{1}{6} Re_p^{2/3}\right) & R e_{p}<1000 \\ C_D=0.424 & Re_p \geqslant 1000 \end{array} C D = R e p 2 4 ( 1 + 6 1 R e p 2 / 3 ) C D = 0 . 4 2 4 R e p < 1 0 0 0 R e p ⩾ 1 0 0 0
R e p = ρ g ∣ v r e l ∣ d p / μ g R e_{p}=\rho_{g}\left|\mathbf{v}_{\mathrm{rel}}\right| d_{p} / \mu_{g} R e p = ρ g ∣ v r e l ∣ d p / μ g
v r e l = u ~ + u ′ − u p \mathbf{v}_{\mathrm{rel}}=\tilde{\mathbf{u}}+\mathbf{u}^{\prime}-\mathbf{u}_{\mathrm{p}} v r e l = u ~ + u ′ − u p
τ p = ρ l d p 2 / 18 ρ g v g \tau_{p}=\rho_{l} d_{p}^{2} / 18 \rho_{g} v_{g} τ p = ρ l d p 2 / 1 8 ρ g v g
u ~ \tilde{\mathbf{u}} u ~ 是气相速度,u ′ \mathbf{u}^{\prime} u ′ is stochastic velocity vector accounting for turbulence dispersion of parcels via interaction with surrounding gases.u ′ \mathbf{u}^{\prime} u ′ 是高斯分布,均值等于 0,方差等于σ 2 = 2 k / 3 \sigma^2=2 k / 3 σ 2 = 2 k / 3 。
若随机变量X服从一个数学期望为 μ、方差为 σ^2 的正态分布,记为 N(μ,σ^2)。
In this way each component ofu ′ \mathbf{u}^{\prime} u ′ is chosen randomly from the Gaussian distribution
G ( u p , i ′ ) = 1 σ 2 π exp ( − u p , i ′ 2 σ ) 2 G\left(\mathbf{u}_{\mathbf{p}, \mathbf{i}}^{\prime}\right)=\frac{1}{\sigma \sqrt{2 \pi}} \exp \left(-\frac{\mathbf{u}_{\mathbf{p}, \mathbf{i}}^{\prime}}{2 \sigma}\right)^{2} G ( u p , i ′ ) = σ 2 π 1 exp ( − 2 σ u p , i ′ ) 2
t t u r b = min ( k ε , C p s k 3 / 2 ε 1 ∣ u ~ + u ′ − u p ∣ ) t_{t u r b}=\min \left(\frac{k}{\varepsilon}, C_{p s} \frac{k^{3 / 2}}{\varepsilon} \frac{1}{\left|\tilde{\mathbf{u}}+\mathbf{u}^{\prime}-\mathbf{u}_{p}\right|}\right) t t u r b = min ( ε k , C p s ε k 3 / 2 ∣ u ~ + u ′ − u p ∣ 1 )
其中C p s = 0.16432 C_{ps}=0.16432 C p s = 0 . 1 6 4 3 2
OF 中的 stochstic turbulence dispersion 模型代码
template <class CloudType >Foam::vector Foam::StochasticDispersionRAS<CloudType>::update ( const scalar dt, const label celli, const vector& U, const vector& Uc, vector& UTurb, scalar& tTurb ) { Random& rnd = this ->owner ().rndGen (); const scalar cps = 0.16432 ; const scalar k = this ->kPtr_->primitiveField ()[celli]; const scalar epsilon = this ->epsilonPtr_->primitiveField ()[celli] + rootVSmall; const scalar UrelMag = mag (U - Uc - UTurb); const scalar tTurbLoc = min (k/epsilon, cps*pow (k, 1.5 )/epsilon/(UrelMag + small)); if (dt < tTurbLoc) { tTurb += dt; if (tTurb > tTurbLoc) { tTurb = 0 ; const scalar sigma = sqrt (2 *k/3.0 ); const scalar theta = rnd.scalar01 ()*twoPi; const scalar u = 2 *rnd.scalar01 () - 1 ; const scalar a = sqrt (1 - sqr (u)); const vector dir (a*cos(theta), a*sin(theta), u) ; UTurb = sigma*mag (rnd.scalarNormal ())*dir; } } else { tTurb = great; UTurb = Zero; } return Uc + UTurb; }
这个函数在哪里被调用?答:
template <class ParcelType >template <class TrackCloudType >void Foam::KinematicParcel<ParcelType>::calcDispersion ( TrackCloudType& cloud, trackingData& td, const scalar dt ) { td.Uc () = cloud.dispersion ().update ( dt, this ->cell (), U_, td.Uc (), UTurb_, tTurb_ ); }
这个 calcDispersion 函数,把 dispersion 模型中计算出来的 Uc + UTurb,即u ~ + u ′ \tilde{\mathbf{u}}+\mathbf{u}^{\prime} u ~ + u ′ 赋值给了 td.Uc(),即当前 parcel 所在位置的气相速度。 这里更新了传进去 UTurb_和tTurb_,这两个数都是只用于当前这个函数,更新它们是为了下一步使用。 此函数最关键的用处就是更新了 td.Uc(),用于后续的 KinematicParcel::calcVelocity,见这篇本站博文 。
KinematicParcel::move 中调用了 p.calcDispersion(cloud, ttd, dt);。
另外还有 SprayParcel::calcBreakup, breakup 之后,child->calcDispersion(cloud, td, dt);。
其中的 UTurb 就是上边公式中的u ′ \mathbf{u}^{\prime} u ′ ,Uc 是公式中的u ~ \tilde{\mathbf{u}} u ~ ,U 是公式中的u p u_p u p 。
针对 LES 的 dispersion 模型Tsang C-W, Kuo C-W, Trujillo M, et al. Evaluation and validation of large-eddy simulation sub-grid spray dispersion models using high-fidelity volume-of-fluid simulation data and engine combustion network experimental data[J]. International Journal of Engine Research, 2019, 20(6):583–605.
t t u r b = C t u r b 2 Δ ∣ u s g s − u d ∣ t_{turb}=C_{turb} \frac{2 \Delta}{\left|\mathbf{u}_{sgs}-\mathbf{u}_{d}\right|} t t u r b = C t u r b ∣ u s g s − u d ∣ 2 Δ
u ′ = u s g s + u s t o \mathbf{u}^{\prime}=\mathbf{u}_{sgs}+\mathbf{u}_{s t o} u ′ = u s g s + u s t o
u s g s = C s g s ( 2 u ~ − 3 u ~ ~ + u ~ ~ ) \mathbf{u}_{s g s}=C_{s g s}(2 \tilde{\mathbf{u}}-3 \widetilde{\tilde{\mathbf{u}}}+\widetilde{\tilde{\mathbf{u}}}) u s g s = C s g s ( 2 u ~ − 3 u ~ + u ~ )
u s t o \mathbf{u}_{sto} u s t o 是高斯分布,均值是0,方差是σ s g s 2 = C s i g 2 3 k s g s \sigma_{s g s}^{2}=C_{sig} \frac{2}{3} k_{s g s} σ s g s 2 = C s i g 3 2 k s g s ,其中C s i g C_{sig} C s i g 是模型参数。
G ( u s t o , i ) = 1 2 σ s g s 2 π exp ( − u s t o , i 2 2 σ s g s 2 ) G\left(\mathbf{u}_{sto, i}\right)=\frac{1}{\sqrt{2 \sigma_{s g s}^{2} \pi}} \exp \left(-\frac{\mathbf{u}_{sto, i}^{2}}{2 \sigma_{s g s}^{2}}\right) G ( u s t o , i ) = 2 σ s g s 2 π 1 exp ( − 2 σ s g s 2 u s t o , i 2 )
dragCdRe:
template <class CloudType >Foam::scalar Foam::SphereDragForce<CloudType>::CdRe (const scalar Re) { if (Re > 1000.0 ) { return 0.424 *Re; } else { return 24.0 *(1.0 + 1.0 /6.0 *pow (Re, 2.0 /3.0 )); } }
calcCoupled:
template <class CloudType >Foam::forceSuSp Foam::SphereDragForce<CloudType>::calcCoupled ( const typename CloudType::parcelType& p, const typename CloudType::parcelType::trackingData& td, const scalar dt, const scalar mass, const scalar Re, const scalar muc ) const { return forceSuSp(Zero, mass*0.75 *muc*CdRe (Re)/(p.rho ()*sqr (p.d ()))); }
SphereDragForce::calcCoupled 的返回值翻译成公式就是3 m p μ g C D R e 4 ρ p D 2 \dfrac{3m_p\mu_g C_DRe}{4\rho_p D^2} 4 ρ p D 2 3 m p μ g C D R e 。 我们有:
F p = m p d u p d t = 3 m p μ g C D R e 4 ρ p D 2 ( u − u p ) F_p = m_p \dfrac{d \mathbf{u}_p}{d t} =\dfrac{3m_p\mu_gC_DRe}{4\rho_p D^2}(\mathbf{u}-\mathbf{u}_{p}) F p = m p d t d u p = 4 ρ p D 2 3 m p μ g C D R e ( u − u p )
SphereDragForce::calcCoupled 返回值即( u − u p ) (\mathbf{u}-\mathbf{u}_{p}) ( u − u p ) 前边的部分。 该返回值用于 KinematicParcel::calcVelocity 计算新的粒子速度,详细过程见这篇本站博文 。