Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

OpenFOAMの壁関数

32.453 visualizaciones

Publicado el

OpenFOAMに実装されている壁関数の説明資料です。随時更新しています。

Publicado en: Tecnología, Empresariales

OpenFOAMの壁関数

  1. 1. Fumiya Nozaki 最終更新日: 2015年2月8日 日本語版 OpenFOAM 壁関数 Wall Functions
  2. 2. 2 Chapter 0. 壁関数とは? 乱流計算で使用される壁関数の基本を理解しましょう. Keywords: • 乱流 • 対数速度分布 • 𝑦+ • 𝑢+
  3. 3.  乱流では,特に壁近傍において,流速が場所により大きく変化します.  この流速の大きな勾配を計算でどのように扱えば良いでしょうか? 3 壁近傍の流速の分布 https://www.linkedin.com/pulse/20140725081243-58050580-y-wall-function-in-cfd
  4. 4. 4 基本的な2つのアプローチ  物体近傍の流速の大きな勾配を取り扱う方法は,大きく次の2種類に分類できます.  高Reモデル (壁関数) • 物体境界に隣接するセルの中心点が 対数則領域にあるようなメッシュを 使用します. 目安: 30 < 𝑦 𝑃 + < 200 • 壁関数のアプローチでは,境界条件は 上記の仮定 (下線部) を用いて 導出されています. • 高Re型の乱流モデルで使用します. wall  低Reモデル • 空間勾配を解像するために,物体近傍にお いて,壁側に密のメッシュを使用します. 目安: 𝑦 𝑃 + ~1 • 低Re型の乱流モデルで使用します. wall 𝑦 𝑃 + > 30 対数則領域 バッファー層 & 粘性底層 𝑦 𝑃 + ~1
  5. 5. 5 壁関数の説明の前に  壁面上の流速の勾配は,N-S 方程式の拡散項を離散化する際に, 壁面せん断応力 (wall shear stress) 𝜏 𝑤 を計算するのに必要です.  壁面に隣接する計算格子が壁面法線方向に粗い場合, 通常の差分では,流速の壁面法線方向 𝒏 の勾配が正しく評価できません. 勾配を上式のように近似した場合,壁面せん断応力も正しく計算できません. wall ∆𝑦 𝑈 𝑃 𝜏 𝑤 𝜕𝑈 𝜕𝒏 𝑤𝑎𝑙𝑙 ≠ ∆𝑈 ∆𝑦 = 𝑈 𝑃 𝑦 𝑃 𝜏 𝑤 = 𝜇 𝜕𝑈 𝜕𝒏 𝑤𝑎𝑙𝑙 ≠ 𝜇 𝑈 𝑃 𝑦 𝑃 𝒏
  6. 6. 6 対数速度分布  対数則領域 (log-law layer) では, 一般的に次の対数速度分布を示すことが知られています. 𝑈+ = 1 𝜅 ln 𝐸𝑦+ • 無次元量 𝑦+ = 𝑦𝑢 𝜏 𝜈 , 𝑈+ = 𝑈 𝑢 𝜏 • 摩擦速度 (friction velocity) 𝑢 𝜏 = 𝜏 𝑤 𝜌 • カルマン定数 κ = 0.41 • 𝐸 = 9.8 1 例外がある点に注意(剥離流れなど)
  7. 7. 7 壁関数の基本的なアプローチ  壁関数では,速度分布に関する関係式 を使用します.  前のページに記載した摩擦速度の定義式と 式を使うと,壁面せん断応力 𝜏 𝑤 は, 次のように表現できます. 𝜏 𝑤 = 𝜌𝑢 𝜏 2 = 𝜌𝜅𝑢 𝜏 𝑈 ln 𝐸𝑦+  この関係式を壁面に隣接するセルの中心点で考えると,添え字P を付けて, 𝜏 𝑤 = 𝜌𝜅𝑢 𝜏 𝑦 𝑃 ln 𝐸𝑦 𝑃 + 𝑈 𝑃 𝑦 𝑃 = 𝜇𝜅𝑦 𝑃 + ln 𝐸𝑦 𝑃 + 𝑈 𝑃 𝑦 𝑃 と変形できます.  この式と5ページの式とを見比べると, 速度勾配を赤枠内の精度の低い差分式で計算した場合でも,壁面での実効的な 粘性係数を青枠内のように計算すれば,壁面せん断応力を正しく評価できるこ とが分かります. 1 1 次ページに続きます.
  8. 8.  流体の粘性係数 𝜇 と乱流の渦粘性係数 𝜇 𝑡 の和を 𝜇 𝑒𝑓𝑓 と表すと, 𝜇 𝑒𝑓𝑓 𝑤𝑎𝑙𝑙 = 𝜇 + 𝜇 𝑡 𝑤𝑎𝑙𝑙 = 𝜇𝜅𝑦 𝑃 + ln 𝐸𝑦 𝑃 +  これを渦粘性係数について解くと,次式が得られます. 𝜇 𝑡 𝑤𝑎𝑙𝑙 = 𝜇 𝜅𝑦 𝑃 + ln 𝐸𝑦 𝑃 + − 1 𝑘𝑔 𝑚 ∙ 𝑠  この式の両辺を密度 𝜌 で割れば,渦動粘性係数の関係式が得られます. 𝜈𝑡 𝑤𝑎𝑙𝑙 = 𝜈 𝜅𝑦 𝑃 + ln 𝐸𝑦 𝑃 + − 1 𝑚2 𝑠 8 壁関数の基本的なアプローチ 非圧縮性流体計算 で使用する式 2 圧縮性流体計算 で使用する式
  9. 9. 9 渦動粘性係数の境界条件 (非圧縮性流れ計算用)  OpenFOAMで壁関数を使用する場合,渦動粘性係数 𝜈𝑡 (“nut” と表記) の 境界条件として以下のものが使用できます.  名前の先頭に ”nut” が付いています.  この中で, “nutkWallFunction” と “nutUWallFunction” の 2つが,8ページの関係式を 使用しています.  ソースコードのディレクトリ src/turbulenceModels/incompressible /RAS/derivedFvPatchFields /wallFunctions/nutWallFunctions  名前に “Rough” と付いているものは, 壁面粗さを考慮した計算用です. nut 用の境界条件 nutLowReWallFunction nutURoughWallFunction nutUSpaldingWallFunction nutUTabulatedWallFunction nutUWallFunction nutWallFunction nutkAtmRoughWallFunction nutkRoughtWallFunction nutkWallFunction
  10. 10. 10 乱流変数の境界条件 (非圧縮性流れ計算用)  OpenFOAMで壁関数を使用する場合,乱流変数 (乱流エネルギー 𝑘 や エネルギー散逸率 𝜀 など) についても適切な境界条件を使用する必要があります. 乱流変数用の境界条件 kqRWallFunction kLowReWallFunction epsilonWallFunction epsilonLowReWallFunction omegaWallFunction v2WallFunction fWallFunction alphatJayatillekeWallFunction  名前の先頭に変数名が付いています.  ソースコードのディレクトリ src/turbulenceModels/incompressible /RAS/derivedFvPatchFields /wallFunctions 次章から,それぞれの境界条件を見ていきましょう.
  11. 11. 11 Chapter 1. nutkWallFunction スタンダードな壁関数です.
  12. 12. 12 壁面上の渦動粘性係数の計算 tmp<scalarField> nutkWallFunctionFvPatchScalarField::calcNut() const { const label patchi = patch().index(); const turbulenceModel& turbModel = db().lookupObject<turbulenceModel>("turbulenceModel"); const scalarField& y = turbModel.y()[patchi]; const tmp<volScalarField> tk = turbModel.k(); const volScalarField& k = tk(); const tmp<volScalarField> tnu = turbModel.nu(); const volScalarField& nu = tnu(); const scalarField& nuw = nu.boundaryField()[patchi]; const scalar Cmu25 = pow025(Cmu_); tmp<scalarField> tnutw(new scalarField(patch().size(), 0.0)); scalarField& nutw = tnutw(); forAll(nutw, faceI) { label faceCellI = patch().faceCells()[faceI]; scalar yPlus = Cmu25*y[faceI]*sqrt(k[faceCellI])/nuw[faceI]; if (yPlus > yPlusLam_) { nutw[faceI] = nuw[faceI]*(yPlus*kappa_/log(E_*yPlus) - 1.0); } } return tnutw; } nutw[faceI]は, faceI番目のフェイスでの 渦粘性係数の値です. nutkWallFunctionFvPatchScalarField.C 2 式です.
  13. 13. 13 壁面上の渦粘性係数の計算 𝜈𝑡 𝑤𝑎𝑙𝑙 = 𝜈 𝜅𝑦+ ln 𝐸𝑦+ − 1 0 𝑦+ > 𝑦𝑙𝑎𝑚 + 𝑦+ ≤ 𝑦𝑙𝑎𝑚 + 𝑦+ = 𝐶𝜇 1 4 𝑦 𝑘 𝜈  壁面上の渦動粘性係数の値を, 𝑦+ と 𝑦𝑙𝑎𝑚 + の大小関係により場合分けして計算します. 𝑦+ > 𝑦𝑙𝑎𝑚 + 𝑦+ ≤ 𝑦𝑙𝑎𝑚 + ここで, 𝑢 𝜏 = 𝐶𝜇 1 4 𝑘 という関係式を使用しています. これが,”nutkWallFunction” の名前の由来です. yPlusLam
  14. 14. 14 yPlusLamの計算 scalar nutWallFunctionFvPatchScalarField::yPlusLam ( const scalar kappa, const scalar E ) { scalar ypl = 11.0; for (int i=0; i<10; i++) { ypl = log(max(E*ypl, 1))/kappa; } return ypl; } nutWallFunctionFvPatchScalarField.C  yPlusLamは,次の2つの関数の交点での 𝑦+ の値を表します. 𝑈+ = 𝑦+ 𝑈+ = 1 𝜅 ln 𝐸𝑦+
  15. 15. 15 yPlusLamの計算  yPlusLamの値は反復法 [1] により計算しています. 𝐸 = 9.8,𝜅 = 0.41 の場合に実際に計算してみると, • 初期値 ypl = 11 • i=0 ypl = 11.415311362133 • i=1 ypl = 11.505702297229 • i=2 ypl = 11.524939390450 • i=3 ypl = 11.529013940444 • i=4 ypl = 11.529876085585 • i=5 ypl = 11.530058470168 • i=6 ypl = 11.530097051410 • i=7 ypl = 11.530105212724 • i=8 ypl = 11.530106939131 • i=9 ypl = 11.530107304327  小数点以下7桁目まで一致しているのが確認できます. 𝑈+ = 1 𝜅 𝑙𝑛 𝐸𝑦+ = 11.53010738
  16. 16. 16 𝑦 + の計算 tmp<scalarField> nutkWallFunctionFvPatchScalarField::yPlus() const { const label patchi = patch().index(); const turbulenceModel& turbModel = db().lookupObject<turbulenceModel>("turbulenceModel"); const scalarField& y = turbModel.y()[patchi]; const tmp<volScalarField> tk = turbModel.k(); const volScalarField& k = tk(); tmp<scalarField> kwc = k.boundaryField()[patchi].patchInternalField(); const tmp<volScalarField> tnu = turbModel.nu(); const volScalarField& nu = tnu(); const scalarField& nuw = nu.boundaryField()[patchi]; return pow025(Cmu_)*y*sqrt(kwc)/nuw; }  “yPlusRAS” ユーティリティを使用して,𝑦 + の値を計算する際に,各境界条件で定義 されている yPlus() が呼ばれます. nutkWallFunctionFvPatchScalarField.C
  17. 17. 17 yPlusRAS const volScalarField::GeometricBoundaryField nutPatches = RASModel->nut()().boundaryField(); bool foundNutPatch = false; forAll(nutPatches, patchi) { if (isA<wallFunctionPatchField>(nutPatches[patchi])) { foundNutPatch = true; const wallFunctionPatchField& nutPw = dynamic_cast<const wallFunctionPatchField&> (nutPatches[patchi]); yPlus.boundaryField()[patchi] = nutPw.yPlus(); const scalarField& Yp = yPlus.boundaryField()[patchi]; Info<< "Patch " << patchi << " named " << nutPw.patch().name() << " y+ : min: " << gMin(Yp) << " max: " << gMax(Yp) << " average: " << gAverage(Yp) << nl << endl; } } yPlusRAS.C ここから呼ばれます.
  18. 18. 18 Chapter 2. nutUWallFunction 対数速度分布の式を直接的に使用した もっともシンプルな壁関数です.
  19. 19.  この壁関数では,𝑦+ の値を対数速度分布の式から計算します. 𝑈 𝑃 𝑢 𝜏 = 1 𝜅 ln 𝐸𝑦 𝑃 +  両辺 𝑦 𝑃 𝜈 倍して,整理すると次式が得られます. 𝑦 𝑃 + ln 𝐸𝑦 𝑃 + = 𝜅𝑈 𝑃 𝑦 𝑃 𝜈  前のステップの流速場 𝑈 𝑃 を上式に代入して解けば,𝑦 𝑃 + の値を計算できます. この非線形方程式の解を,Newton-Raphson 法を使用して求めます.  得られた 𝑦 𝑃 + の値を次式に代入して,壁面上の渦動粘性係数の値を計算します. 19 壁面上の渦動粘性係数の計算 𝜈𝑡 𝑤𝑎𝑙𝑙 = 𝜈 𝜅𝑦+ ln 𝐸𝑦+ − 1 0 𝑦+ > 𝑦𝑙𝑎𝑚 + 𝑦+ ≤ 𝑦𝑙𝑎𝑚 + 3
  20. 20. 20 Newton-Raphson 法による解法  方程式 の解 𝑦 𝑃 + を,Newton-Raphson 法により求めます. 𝑓 𝑦 𝑃 + = 𝑦 𝑃 + ln 𝐸𝑦 𝑃 + − 𝜅𝑈 𝑃 𝑦 𝑃 𝜈 = 0 Newton-Raphson 法の漸化式 𝑦 𝑛+1 + = 𝑦𝑛 + − 𝑓 𝑦𝑛 + 𝑓′ 𝑦𝑛 + = 𝑦𝑛 + − 𝑦𝑛 + ln 𝐸𝑦𝑛 + − 𝜅𝑈 𝑃 𝑦 𝑃 𝜈 1 + ln 𝐸𝑦𝑛 + = 𝜅𝑈 𝑃 𝑦 𝑃 𝜈 + 𝑦𝑛 + 1 + ln 𝐸𝑦𝑛 +  この反復計算が,calcYPlus に実装されています. 3 この添え字は, 反復回数です.
  21. 21. 21 calcYPlus forAll(yPlus, facei) { scalar kappaRe = kappa_*magUp[facei]*y[facei]/nuw[facei]; scalar yp = yPlusLam_; scalar ryPlusLam = 1.0/yp; int iter = 0; scalar yPlusLast = 0.0; do { yPlusLast = yp; yp = (kappaRe + yp)/(1.0 + log(E_*yp)); } while (mag(ryPlusLam*(yp - yPlusLast)) > 0.01 && ++iter < 10 ); yPlus[facei] = max(0.0, yp); } 𝑦 𝑛+1 𝑃 = 𝜅𝑈 𝑃 𝑦 𝑃 𝜈 + 𝑦𝑛 + 1 + ln 𝐸𝑦𝑛 + nutUWallFunctionFvPatchScalarField.C
  22. 22. 22 Chapter 3. nutUSpaldingWallFunction
  23. 23. 23 Spalding則 𝑦+ = 𝑢+ + 1 𝐸 𝑒 𝜅𝑢+ − 1 − 𝜅𝑢+ − 1 2 𝜅𝑢+ 2 − 1 6 𝜅𝑢+ 3  Eugene de Villiers 博士の博士論文 [2] Spalding 則
  24. 24. 24 Spalding則  この 𝑦+ と 𝑢+ の関係式は,粘性底層での関係式 𝑢+ = 𝑦+ と対数則領域での関係式 𝑢+ = 1 𝜅 ln 𝐸𝑦+ をうまくフィッテイングした関数です. 𝑦+ 𝑢+ Spalding 則 𝑢+ = 𝑦+ 𝑢+ = 1 𝜅 ln 𝐸𝑦+
  25. 25. 25 壁面上の渦粘性係数の計算 tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::calcNut() const { const label patchI = patch().index(); const turbulenceModel& turbModel = db().lookupObject<turbulenceModel>("turbulenceModel"); const fvPatchVectorField& Uw = turbModel.U().boundaryField()[patchI]; const scalarField magGradU(mag(Uw.snGrad())); const tmp<volScalarField> tnu = turbModel.nu(); const volScalarField& nu = tnu(); const scalarField& nuw = nu.boundaryField()[patchI]; return max ( scalar(0), sqr(calcUTau(magGradU))/(magGradU + ROOTVSMALL) - nuw ); } 𝜈𝑡 𝑤𝑎𝑙𝑙 = 𝑢 𝜏 2 𝜕𝒖 𝜕𝒏 − 𝜈 nutUSpaldingWallFunctionFvPatchScalarField.C 壁面摩擦速度 𝑢 𝜏 を Spalding則 から計算します.
  26. 26. 26 壁面摩擦速度 𝑢 𝜏 の計算 tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::calcUTau ( const scalarField& magGradU ) const { const label patchI = patch().index(); const turbulenceModel& turbModel = db().lookupObject<turbulenceModel>("turbulenceModel"); const scalarField& y = turbModel.y()[patchI]; const fvPatchVectorField& Uw = turbModel.U().boundaryField()[patchI]; const scalarField magUp(mag(Uw.patchInternalField() - Uw)); const tmp<volScalarField> tnu = turbModel.nu(); const volScalarField& nu = tnu(); const scalarField& nuw = nu.boundaryField()[patchI]; const scalarField& nutw = *this; tmp<scalarField> tuTau(new scalarField(patch().size(), 0.0)); scalarField& uTau = tuTau(); nutUSpaldingWallFunctionFvPatchScalarField.C 次のページに続く.
  27. 27. 27 壁面摩擦速度 𝑢 𝜏 の計算 forAll(uTau, faceI) { scalar ut = sqrt((nutw[faceI] + nuw[faceI])*magGradU[faceI]); if (ut > ROOTVSMALL) { int iter = 0; scalar err = GREAT; do { scalar kUu = min(kappa_*magUp[faceI]/ut, 50); scalar fkUu = exp(kUu) - 1 - kUu*(1 + 0.5*kUu); scalar f = - ut*y[faceI]/nuw[faceI] + magUp[faceI]/ut + 1/E_*(fkUu - 1.0/6.0*kUu*sqr(kUu)); scalar df = y[faceI]/nuw[faceI] + magUp[faceI]/sqr(ut) + 1/E_*kUu*fkUu/ut; scalar uTauNew = ut + f/df; err = mag((ut - uTauNew)/ut); ut = uTauNew; } while (ut > ROOTVSMALL && err > 0.01 && ++iter < 10); uTau[faceI] = max(0.0, ut); } } Newton-Raphson法を 使用して壁面摩擦速度 𝑢 𝜏 を反復計算で求めています. 漸化式 反復継続条件 nutUSpaldingWallFunctionFvPatchScalarField.C
  28. 28. 28 壁面摩擦速度 𝑢 𝜏 の計算  calcUTau() では,Spalding則を満たす 𝑢 𝜏 を Newton-Raphson法により求めます. 𝑓 𝑢 𝜏, 𝑦, 𝑢 = −𝑦+ + 𝑢+ + 1 𝐸 𝑒 𝜅𝑢+ − 1 − 𝜅𝑢+ − 1 2 𝜅𝑢+ 2 − 1 6 𝜅𝑢+ 3 = 0 Newton-Raphsonの漸化式 𝑢 𝜏 𝑛+1 = 𝑢 𝜏 𝑛 − 𝑓 𝑢 𝜏 𝑛, 𝑦, 𝑢 𝑓′ 𝑢 𝜏 𝑛 , 𝑦, 𝑢  壁面隣接セル中心における • 𝑦 の値,つまり壁面からの距離と • 各時間ステップでの流速 𝑢 が既知なので,ただ1つの未知数である 𝑢 𝜏 について解くことができます. ソースコードの中では -df
  29. 29. 29 𝑦 + の計算 tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::yPlus() const { const label patchi = patch().index(); const turbulenceModel& turbModel = db().lookupObject<turbulenceModel>("turbulenceModel"); const scalarField& y = turbModel.y()[patchi]; const fvPatchVectorField& Uw = turbModel.U().boundaryField()[patchi]; const tmp<volScalarField> tnu = turbModel.nu(); const volScalarField& nu = tnu(); const scalarField& nuw = nu.boundaryField()[patchi]; return y*calcUTau(mag(Uw.snGrad()))/nuw; } nutUSpaldingWallFunctionFvPatchScalarField.C
  30. 30. 30 Chapter 4. nutLowReWallFunction
  31. 31. 31 壁面上の渦粘性係数の計算 tmp<scalarField> nutLowReWallFunctionFvPatchScalarField::calcNut() const { return tmp<scalarField>(new scalarField(patch().size(), 0.0)); } nutLowReWallFunctionFvPatchScalarField.C  ヘッダーファイルの説明文 Description This boundary condition provides a turbulent kinematic viscosity condition for use with low Reynolds number models. It sets nut to zero, and provides an access function to calculate y+.  calcNut() で壁面上の渦粘性係数を0に設定しています. 𝜈𝑡 𝑤𝑎𝑙𝑙 = 0 1 2 1
  32. 32. 32 𝑦 + の計算 tmp<scalarField> nutLowReWallFunctionFvPatchScalarField::yPlus() const { const label patchi = patch().index(); const turbulenceModel& turbModel = db().lookupObject<turbulenceModel>("turbulenceModel"); const scalarField& y = turbModel.y()[patchi]; const tmp<volScalarField> tnu = turbModel.nu(); const volScalarField& nu = tnu(); const scalarField& nuw = nu.boundaryField()[patchi]; const fvPatchVectorField& Uw = turbModel.U().boundaryField()[patchi]; return y*sqrt(nuw*mag(Uw.snGrad()))/nuw; } nutLowReWallFunctionFvPatchScalarField.C  前のスライドで見たように,“fixedValue” 条件で nut の値を 0 に規定した場合と同じ 計算になります.  1つの違いは,”nutLowReWallFunction” 条件を使用した場合には,”yPlusRAS” ユーティリティを使って 𝑦+ の値を計算できる点です. 2 𝑦+ = 𝑦 𝑢 𝜏 𝜈 = 𝑦 𝜏 𝑤 𝜌 𝜈 = 𝑦 𝜈 𝜕𝒖 𝜕𝒏 𝑤𝑎𝑙𝑙 𝜈
  33. 33. 33 Chapter 5. kqRWallFunction Keywords: • 乱流エネルギー 𝑘 • 𝑞 − 𝜁 モデルの変数 𝑞 • レイノルズ応力テンソル 𝑅
  34. 34. 34 概要 template<class Type> void kqRWallFunctionFvPatchField<Type>::evaluate ( const Pstream::commsTypes commsType ) { zeroGradientFvPatchField<Type>::evaluate(commsType); }  kqRWallFunction は, • 乱流エネルギー 𝑘 • 𝑞 − 𝜁 (qZeta) モデルの変数 𝑞 • Launder-Reece-Rodi RSTM (LRR) のレイノルズ応力テンソル 𝑅 に対して,法線方向勾配値が0 (zeroGradient) の条件を課します. 𝒏 ∙ 𝛻𝑘 = 0 𝑒𝑡𝑐.  ソースコードを見ると,zeroGradient 条件を呼んでいるのが確認できます. kqRWallFunctionFvPatchField.C
  35. 35. 35 Chapter 6. kLowReWallFunction Keywords: • 𝑣2 − 𝑓 (v2f) モデル
  36. 36. 36 概要  kLowReWallFunction は, • 𝑣2 − 𝑓 (v2f) モデルの乱流エネルギー 𝑘 に対して,以下の条件を設定します [3].  𝑦+ > 𝑦𝑙𝑎𝑚 + のとき (壁面隣接セル中心点が対数則領域にある場合) 𝑘+ = 𝐶 𝑘 𝜅 ln 𝑦+ + 𝐵 𝑘  𝑦+ ≤ 𝑦𝑙𝑎𝑚 + のとき 𝑘+ = 2400 𝐶ε2 2 1 𝑦+ + 𝐶 2 + 2𝑦+ 𝐶3 − 1 𝐶2 ここで, 𝑘+ = 𝑘 𝑢 𝜏 2 , 𝐶 𝑘 = −0.416, 𝐵 𝑘 = 8.366, 1𝐶 = 11.0, 𝐶𝜀2 = 1.9 𝑦𝑙𝑎𝑚 + については 第1章を ご覧ください.
  37. 37. 37 ソースコード // Set k wall values forAll(kw, faceI) { label faceCellI = patch().faceCells()[faceI]; scalar uTau = Cmu25*sqrt(k[faceCellI]); scalar yPlus = uTau*y[faceI]/nuw[faceI]; if (yPlus > yPlusLam_) { scalar Ck = -0.416; scalar Bk = 8.366; kw[faceI] = Ck/kappa_*log(yPlus) + Bk; } else { scalar C = 11.0; scalar Cf = (1.0/sqr(yPlus + C) + 2.0*yPlus/pow3(C) - 1.0/sqr(C)); kw[faceI] = 2400.0/sqr(Ceps2_)*Cf; } kw[faceI] *= sqr(uTau); kLowReWallFunctionFvPatchScalarField.C 𝐶𝜀2 以外の定数は ハードコードされています.
  38. 38. 38 Chapter 7. epsilonWallFunction Keywords: • 乱流エネルギー散逸率 𝜀
  39. 39. 39 概要  epsilonWallFunction は,高Re型の乱流モデルにおいて使用し, 乱流エネルギー散逸率 𝜀 の境界条件を設定します.  他の境界条件とは異なり,この条件は,境界上での値ではなく, 境界に隣接するセルの中心点での値を計算します. 𝜀 𝑃 = 𝐶𝜇 3 4 𝑘 𝑃 3 2 𝜅𝑦 𝑃  エッジ上や角部にあるセルのように,複数のフェイスが この条件を指定した壁面上にある場合,算術平均を計算します. wall wall 例えば左図のように, 2つのフェイスが壁面上にある場合, それぞれのフェイスで上式を使用すると, 2つの値 𝜀 𝑃 1 , 𝜀 𝑃 2 を計算できます. この場合,これを次式のように平均します. 𝜀 𝑃 = 𝜀 𝑃 1 + 𝜀 𝑃 2 2 𝜀 𝑃 1 𝜀 𝑃 2
  40. 40. 40 ソースコード // Set epsilon and G forAll(nutw, faceI) { label cellI = patch.faceCells()[faceI]; scalar w = cornerWeights[faceI]; epsilon[cellI] += w*Cmu75*pow(k[cellI], 1.5)/(kappa_*y[faceI]); G[cellI] += w *(nutw[faceI] + nuw[faceI]) *magGradUw[faceI] *Cmu25*sqrt(k[cellI]) /(kappa_*y[faceI]); }  セル中心値 𝜀 𝑃 の計算 cornerWeights の値が,epsilonWallFunction 条件を指定した 境界上にあるフェイス数の逆数です. 乱流エネルギー生産率 𝐺 の値も計算しています. epsilonWallFunctionFvPatchScalarField.C
  41. 41. 41 連立方程式での取り扱い  例えば,標準 𝑘 − 𝜀 モデルの場合,エネルギー散逸率 𝜀 の支配方程式を離散化して解く ので,epsilonWallFunction を指定した境界に隣接するセルで特別な処理が必要です. // Update epsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); // Dissipation equation tmp<fvScalarMatrix> epsEqn ( fvm::ddt(epsilon_) + fvm::div(phi_, epsilon_) - fvm::laplacian(DepsilonEff(), epsilon_) == C1_*G*epsilon_/k_ - fvm::Sp(C2_*epsilon_/k_, epsilon_) ); epsEqn().relax(); epsEqn().boundaryManipulate(epsilon_.boundaryField()); solve(epsEqn); bound(epsilon_, epsilonMin_); epsilonWallFunction 条件を 指定した境界に隣接するセル では,連立方程式を解かず, 35ページの計算式から 乱流エネルギー散逸率を計算. boundaryManipulate は, setValues 関数を呼び出して, これらのセルでの離散化式を 連立方程式から取り除く操作を 行っています. kEpsilon.C
  42. 42. 42 付録 Keywords: • wallShearStress ユーティリティ
  43. 43. 43 壁面せん断応力ベクトル  N-S 方程式の拡散項の離散化 𝜕 𝜕𝑥𝑗 𝜈 + 𝜈𝑡 𝜕𝑢𝑖 𝜕𝑥𝑗 + 𝜕𝑢𝑗 𝜕𝑥𝑖 𝑑𝑉 ∆𝑉 ~ 𝜈 + 𝜈𝑡 𝑓 𝑛 𝑓 𝑗 𝜕𝑢𝑖 𝜕𝑥𝑗 + 𝜕𝑢𝑗 𝜕𝑥𝑖 ∆𝑆𝑓 𝑓 戻る せん断応力ベクトル 𝜈 + 𝜈𝑡 𝜕𝑢1 𝜕𝑥1 + 𝜕𝑢1 𝜕𝑥1 𝜕𝑢1 𝜕𝑥2 + 𝜕𝑢2 𝜕𝑥1 𝜕𝑢1 𝜕𝑥3 + 𝜕𝑢3 𝜕𝑥1 𝜕𝑢2 𝜕𝑥1 + 𝜕𝑢1 𝜕𝑥2 𝜕𝑢2 𝜕𝑥2 + 𝜕𝑢2 𝜕𝑥2 𝜕𝑢2 𝜕𝑥3 + 𝜕𝑢3 𝜕𝑥2 𝜕𝑢3 𝜕𝑥1 + 𝜕𝑢1 𝜕𝑥3 𝜕𝑢3 𝜕𝑥2 + 𝜕𝑢2 𝜕𝑥3 𝜕𝑢3 𝜕𝑥3 + 𝜕𝑢3 𝜕𝑥3 𝑇 𝑛1 𝑛2 𝑛3 添え字 f を省略しています. 4
  44. 44. 44 wallShearStress ユーティリティ  RANS 計算を行った場合には,wallShearStress ユーティリティを使用して, 境界上のせん断応力ベクトルの計算が可能です. singlePhaseTransportModel laminarTransport(U, phi); autoPtr<incompressible::RASModel> model ( incompressible::RASModel::New(U, phi, laminarTransport) ); const volSymmTensorField Reff(model->devReff()); forAll(wallShearStress.boundaryField(), patchI) { wallShearStress.boundaryField()[patchI] = ( -mesh.Sf().boundaryField()[patchI] /mesh.magSf().boundaryField()[patchI] ) & Reff.boundaryField()[patchI]; } 応力テンソルの計算 各 RANS モデルのクラス で定義されています. 4 式を使用しています. wallShearStress.C
  45. 45. 45 応力テンソルの計算 tmp<volSymmTensorField> kEpsilon::devReff() const { return tmp<volSymmTensorField> ( new volSymmTensorField ( IOobject ( "devRhoReff", runTime_.timeName(), mesh_, IOobject::NO_READ, IOobject::NO_WRITE ), -nuEff()*dev(twoSymm(fvc::grad(U_))) ) ); }  deVReff() は,それぞれの RANS モデルのクラスで実装されており, 応力テンソルを計算します. kEpsilon.C − 𝜈 + 𝜈𝑡 𝜕𝑢1 𝜕𝑥1 + 𝜕𝑢1 𝜕𝑥1 𝜕𝑢1 𝜕𝑥2 + 𝜕𝑢2 𝜕𝑥1 𝜕𝑢1 𝜕𝑥3 + 𝜕𝑢3 𝜕𝑥1 𝜕𝑢2 𝜕𝑥1 + 𝜕𝑢1 𝜕𝑥2 𝜕𝑢2 𝜕𝑥2 + 𝜕𝑢2 𝜕𝑥2 𝜕𝑢2 𝜕𝑥3 + 𝜕𝑢3 𝜕𝑥2 𝜕𝑢3 𝜕𝑥1 + 𝜕𝑢1 𝜕𝑥3 𝜕𝑢3 𝜕𝑥2 + 𝜕𝑢2 𝜕𝑥3 𝜕𝑢3 𝜕𝑥3 + 𝜕𝑢3 𝜕𝑥3 非圧縮性流れ 計算の場合 dev は,偏差応力テンソルを計算します.
  46. 46. 46 偏差応力テンソルの計算  非圧縮性流れの場合には,連続の式より,トレースの値が 0 なので, dev(twoSymm(fvc::grad(U_))) = twoSymm(fvc::grad(U_)) の関係が成り立っています.  dev は,偏差応力テンソル (deviatoric stress tensor) を計算します ([4] 20ページ).
  47. 47. 47 参考資料 [1] http://www.index-press.co.jp/books/excel/ex-nv06.pdf [2] http://powerlab.fsb.hr/ped/kturbo/OpenFOAM/docs/EugeneDeVilliersPhD2006.pdf [3] http://www.os- cfd.ru/cfd_docs/wall_funcs/Near_wall_behaviour_of_RANS_and_implications_for _wall_functions.pdf [4] OpenFOAM Programmer’s Guide http://foam.sourceforge.net/docs/Guides-a4/ProgrammersGuide.pdf
  48. 48. 48 Thank You!

×