Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

OpenFOAMの壁関数

32,401 views

Published on

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

Published in: Technology, Business
  • nice, but translate to enflish
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Please, help us and translate it into English
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Nice work
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

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!

×