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 -空間の離散化と係数行列の取り扱い(Spatial Discretization and Coefficient Matrix)-

38,231 views

Published on

Published in: Technology
  • ..............ACCESS that WEBSITE Over for All Ebooks ................ ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THI5 BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THI5 BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THI5 BOOKS 1NTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

OpenFOAM -空間の離散化と係数行列の取り扱い(Spatial Discretization and Coefficient Matrix)-

  1. 1. OpenFOAM 空間の離散化と係数行列の取り扱い Fumiya Nozaki 最終更新日: 2015年9月23日 日本語版 Keywords: • OpenFOAM • 有限体積法 • 係数行列
  2. 2. 2 Disclaimer “This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks.”
  3. 3. 3 はじめに この資料では, 数値流体力学(CFD)の基本である • 空間の離散化(discretization) や • その結果得られる代数方程式系の係数行列(coefficient matrix)の処理 などについて,オープンソースソフトウェアの1つである OpenFOAM® がど のように行っているのかをできるだけ平易に解説することを目指して作成しま した.
  4. 4. 4 目次  Chapter 1:離散化の概要  Chapter 2:係数行列の表示(ソルバーのカスタマイズ)  Chapter 3:係数行列の表示(gdbOF の使用)  Chapter 4:空間の離散化  Chapter 5:境界条件の離散化  Chapter 6:simpleFoam の解説  Chapter 7:pUCoupledFoam の解説  参考文献
  5. 5. 5 Chapter 1 数値解法の一般的な事柄を理解しましょう.
  6. 6. 6 非圧縮性流体の運動方程式 非圧縮性流体の運動は,次の方程式で記述されます. • 質量保存則(連続の式) 𝛻 ∙ 𝒖 = 0 • 運動量保存則 𝜕𝒖 𝜕𝑡 + 𝒖 ∙ 𝛻 𝒖 = − 1 𝜌 𝛻𝑝 + 𝛻 ∙ 𝜈𝛻𝒖 Navier–Stokes 方程式と呼ばれるこの方程式を解析的に解くことができれば, 各時刻 𝑡,各場所 𝒙 での流速 𝒖 𝒙, 𝑡 ,圧力 𝑝 𝒙, 𝑡 の値を知ることができます が, これを数学的に解く問題は,アメリカのクレイ数学研究所からその解決に100 万ドルの懸賞金がかけられている数学上の未解決問題 [1] の一つであり,非常 に難しい問題です.
  7. 7. 7 近似的なアプローチ 連続の世界で厳密に解く 離散化された世界で近似的に解く 厳密に解くことが難しいので,工学の世界では近似的に解くことが広く行われ ています. 𝒖 𝒙, 𝑡 𝑝 𝒙, 𝑡 𝒖 𝒙𝒊, 𝑡𝑗 𝒙1 𝒙2 𝒙3 𝒙4 𝒙5 𝒙6 𝑝 𝒙𝒊, 𝑡𝑗 時間の離散化:有限個の時刻 𝑡𝑗 での値を求める 空間の離散化:有限個 𝑁 の位置 𝒙𝑖 での流速,圧力の値を求める 上図は,𝑁 = 6 の場合
  8. 8. 隣接する点での変数値がどう関係しているか 上記の離散化の方法により, この関係式を導く考え方が異なります. 8 空間の離散化の方法 空間の離散化には様々な方法があります.  空間の離散化の方法 [2] • 差分法(finite difference method : FDM) • 有限体積法(finite volume method : FVM) • 有限要素法(finite element method : FEM) など  空間の離散化の目的 有限個の位置 𝒙𝑖 での流速や圧力などの変数の値を関係づける代数方程式を導 きます. 𝑝1 𝑝2 𝑝3 𝑝4 𝑝5 𝑝6 𝑐1 𝑝1 + 𝑐2 𝑝2 + 𝑐4 𝑝4 = 0どのような関係?
  9. 9. 9 OpenFOAMでは?  OpenFOAM®では,空間の離散化に有限体積法を使用しています [3].  主要な商用 CFD ソフトウェアの多くも有限体積法を採用しています.  有限体積法の解説 春日さんの資料 [4] が分かりやすくてお勧めです. 面中心での変数の値の計算方法に注意して読んでみて下さい.
  10. 10. 10 空間の離散化の方法  有限体積法では,計算領域を多面体により分割します(下図).  この多面体はコントロールボリューム(以下 CV とも言う)やセルと呼ばれます.  OpenFOAM では • CV には何面体でも使用できます. • CV の各界面は面やフェイス(face)と呼ばれ,何角形でも使用できます. • 内部フェイスには必ずその両側にそれを共有する2つの CV が存在します. • 全ての変数値は CV の中心点で求められます(コロケート格子). フェイス f の両側に2つの コントロールボリューム 7面体のCV 6面体のCV
  11. 11. 11 フェイス中心の値の計算  有限体積法ではガウス積分を使用して,各コントロールボリュームでの体積積 分をその界面であるフェイスでの面積積分に変換して計算します. 例えば,勾配項 𝛻𝜙 は,  OpenFOAMのフェイス中心での値の計算 変数の値はセル中心において計算されるので,各フェイスについてその両側に ある2つのセルの中心での値 𝜙 𝑃,𝜙 𝑁 を用いて,𝜙 𝑓 の値を計算します. 𝛻𝜙𝑑𝑉 𝑉 = 𝜙𝒏𝑑𝑆 𝑆 ~ 𝜙 𝑓 𝑺 𝑓 𝑓 ガウス積分 近似 フェイス中心での値 𝝓 𝒇 が必要! 𝜙 𝑃 𝜙 𝑁𝜙 𝑓
  12. 12. 12 各CVで得られる代数方程式  7ページと8ページの から,OpenFOAMでは 離散化により,各CVでは次式のような代数方程式が得られます. 𝐴 𝑝 𝜙 𝑝 + 𝐴 𝑁 𝜙 𝑁 𝑁 = 𝑠 𝑃 𝜙 𝑝 𝜙 𝑁 注目するCV の各フェイスを共有する 全てのCV に関する和 OpenFOAMでは,あるCVにおける離散化式には, • そのCVのセル中心値と • そのCVとフェイスを共有するCVのセル中心値 のみが現れます.
  13. 13.  各CVで立てた式を連立して解くことで,全てのCV中心での変数値を求める ことができます.  各CVに番号を付けて,係数行列 𝐴 の性質を見てみましょう. 13 係数行列の性質 𝜙1 ⋮ 𝜙9 = 𝑠1 ⋮ 𝑠9 𝐴 係数行列 1 2 3 6 5 4 7 8 9 対角成分 一色で色づけ 値が0ではない成分のみ色づけ 非対角成分 各フェイスについて,その 両側のCVに関係する成分を 同じ色で色づけ 右辺ベクトル
  14. 14. 14 係数行列の性質 1 2 3 6 5 4 7 8 9  2番目のCVと3番目のCVが共有するフェイスを見てみます. 注目するフェイスが離散化に使われるのはこの2ケースです. 2 3 2 3 (ⅰ)2番目のCVで離散化 (ⅱ)3番目のCVで離散化
  15. 15. 15 係数行列の性質 これまでの内容をまとめると,  係数行列の性質 • 非零要素は, -対角成分:CVの数だけ存在 -非対角成分:上三角行列と下三角行列の中に内部フェイスの数ずつ存在 • 上三角行列内の非零要素と下三角行列内の非零要素は,各内部フェイスに 関してペアを構成しています.  OpenFOAMでは,上記の性質を利用して,係数行列の非零要素のみを効率的 に保持しています.
  16. 16. 16 係数行列のデータの持ち方:lduMatrix クラス  OpenFOAMの係数行列のデータの持ち方 係数行列を対角行列と上三角行列と下三角行列とに分けて,それぞれの非零 成分のみを配列に格納しています. • 対角成分の配列: diag • 上三角行列の非零成分の配列: upper • 下三角行列の非零成分の配列: lower □ ⋯ □ ⋮ ⋱ ⋮ □ ⋯ □ 『lduMatrix』クラス upper lower diag 3つの配列 非零成分のみ保存
  17. 17. 17 係数行列のデータの持ち方:lduAddressing クラス 前ページの3つの配列には,係数行列の全ての非零要素が格納されていますが, これだけでは,それらが係数行列の何行何列目の成分なのかが分かりません.  この情報を取り扱うのが,『lduAddressing』クラスです. 具体的には各内部フェイスについて,その番号とその両側にある2つのCVの 番号との対応関係の情報を扱います. • lowerAddr: 小さい方のセル番号 • upperAddr: 大きい方のセル番号 7番目の内部フェイス 3番目のCV 5番目のCV 例えば,左図の場合 𝑙𝑜𝑤𝑒𝑟𝐴𝑑𝑑𝑟 7 = 3 𝑢𝑝𝑝𝑒𝑟𝐴𝑑𝑑𝑟 7 = 5 です.
  18. 18. 18 簡単な例で見てみましょう! -1- -2- -3- -6- -5- -4- -7- -8- -9- (数字はセル番号) 2番目のセルでの離散化式における5番目のセルの係数 𝐴 𝑙𝑜𝑤𝑒𝑟𝐴𝑑𝑑𝑟 𝑘 𝑢𝑝𝑝𝑒𝑟𝐴𝑑𝑑𝑟 𝑘 = 𝑢𝑝𝑝𝑒𝑟 𝑘 5番目のセルでの離散化式における2番目のセルの係数 𝐴 𝑢𝑝𝑝𝑒𝑟𝐴𝑑𝑑𝑟 𝑘 𝑙𝑜𝑤𝑒𝑟𝐴𝑑𝑑𝑟 𝑘 = 𝑙𝑜𝑤𝑒𝑟 𝑘 3×3のメッシュ 係数行列 このフェイスの 番号が 𝑘 だと すると
  19. 19. 19 owner セルと neighbour セル  OpenFOAMでは,内部フェイスの両側にある2つのセル(CV)の内, • 番号が小さい方をそのフェイスの owner セル • 番号が大きい方をそのフェイスの neighbour セル と定義しています.  内部フェイスに関して,lduAddressing クラスでは, 𝐮𝐩𝐩𝐞𝐫𝐀𝐝𝐝𝐫 k > 𝐥𝐨𝐰𝐞𝐫𝐀𝐝𝐝𝐫 k と定義されているため, • 𝐥𝐨𝐰𝐞𝐫𝐀𝐝𝐝𝐫 k : 𝑘 番目のフェイスの owner セル番号 • 𝐮𝐩𝐩𝐞𝐫𝐀𝐝𝐝𝐫 k : 𝑘 番目のフェイスの neighbour セル番号 という関係が成り立ちます.
  20. 20. 20 連立方程式の取り扱い  離散化により得られる連立方程式の解法は『fvMatrix』クラスが担っていま す. • 連立方程式の解法に必要な種々の関数が実装されています: ‐source: ソース項(右辺ベクトル) ‐relax: 係数行列の不足緩和 ‐residual: 残差の計算 ‐faceFluxCorrectionPtr: 非直交補正 ‐flux: 連続式を満たすための流束の修正量 • 境界条件の処理(係数行列の対角成分及びソース項への境界条件からの寄 与の計算)を行います: ‐internalCoeffs: 係数行列の対角成分への寄与 ‐boundaryCoeffs: ソース項への寄与
  21. 21. 21 境界条件の取り扱い  境界条件を離散化したときの,係数行列の対角成分への寄与やソース項への 寄与は,使用する境界条件のタイプ(fixedValue:ディリクレ条件, zeroGradient:ノイマン条件など)により異なります.  OpenFOAMではこれを取り扱うために,境界条件のタイプごとに以下の4つ の関数が定義されており, internalCoeffs 及び boundaryCoeffs はこれ らの関数から計算されます. • 対流項の離散化 - valueInternalCoeffs: 対角成分への寄与 - valueBoundaryCoeffs: ソース項への寄与 • ラプラシアン項の離散化 ‐ gradientInternalCoeffs: 対角成分へ寄与 ‐ gradientBoundaryCoeffs: ソース項への寄与 対流項の流束の計算にはCV界面の値が必要なのに対し,ラプラシアン項の流 束の計算にはCV界面の勾配が必要であり,境界条件の取り扱いが異なるため, 上記のようにそれぞれの項に対し,関数が用意されています.
  22. 22. Chapter 2 実際に1次元のラプラス方程式を解くことで, OpenFOAMへの理解を深めましょう. 22
  23. 23. 23 参考にしたテキスト H.Versteeg, W.Malalasekera 著 『An Introduction to Computational Fluid Dynamics: The Finite Volume Method』  有限体積法について,理論から計算例 の紹介までとても内容が豊富です.  記述も丁寧なので,学生さんにもおす すめです.  著者のホームページ • Henk Versteeg先生 http://www.lboro.ac.uk/departments/mechman/staff/henk-versteeg.html • W.Malalasekera先生 http://lupo.lboro.ac.uk/staff/malalasekera.html お二人とも英国のラフバラー大学の先生です.
  24. 24. 早速,次の定常拡散方程式を数値的に解いてみましょう.  支配方程式:ラプラス方程式  境界条件 24 問題設定:一次元の定常熱伝導問題 𝑑 𝑑𝑥 𝑘 𝑑𝑇 𝑑𝑥 = 0 0.5m A 𝑇𝐴 = 100℃ 𝑇𝐵 = 500℃ B 𝑇 0 = 100 𝑇 0.5 = 500 断面積 10 × 10−3 𝑚2 𝑘 = 1000 𝑊𝑚−1 𝐾−1 熱伝導率
  25. 25. 25 この問題の解析解 この問題の解析解は簡単に求められます. 𝑇 = 800𝑥 + 100 ℃ 線形的な温度変化
  26. 26. 26 何をするの? この問題は,OpenFOAMに付属のソルバーである laplacianFoam を使用することで簡単に解けてしまいますが,ここではこれを改造して, 離散化して得られる係数行列を表示できるようにする ことを目指します.
  27. 27.  laplacianFoam ソルバーのフォルダをコピーして,mylaplacianFoam フォ ルダを作成します.  mylaplacianFoam フォルダに移動し,laplacianFoam.C ファイルの名前を 変更します.  Make フォルダ内の files ファイルの内容を変更します. 27 作業1:準備 $ sol $ cd basic $ cp –r laplacianFoam mylaplacianFoam $ cd mylaplacianFoam $ mv laplacianFoam.C mylaplacianFoam.C laplacianFoam.C EXE = $(FOAM_APPBIN)/laplacianFoam mylaplacianFoam.C EXE = $(FOAM_USER_APPBIN)/mylaplacianFoam 変更前 変更後
  28. 28. 28 作業2:mylaplacianFoam.C の変更 #include "fvCFD.H" #include "simpleControl.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createMesh.H" #include "createFields.H" simpleControl simple(mesh); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "¥nCalculating temperature distribution¥n" << endl; while (simple.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; while (simple.correctNonOrthogonal()) { solve ( fvm::ddt(T) - fvm::laplacian(DT, T) ); } #include "write.H" Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; } Info<< "End¥n" << endl; return 0; } // ************************************************************************* // mylaplacianFoam.C の内容(下記)を次ページのように変更します. 変更前
  29. 29. 29 作業2:mylaplacianFoam.C の変更 #include "fvCFD.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createMesh.H" #include "createFields.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "¥nCalculating temperature distribution¥n" << endl; while (runTime.loop()) { fvScalarMatrix TEqn(fvm::laplacian(k, T)); TEqn.solve(); forAll(T, cellI) { Info<< "X = " << mesh.C()[cellI].component(vector::X) << ", T = " << T[cellI] << endl; } runTime.writeAndEnd(); } Info<< "End¥n" << endl; return 0; } // ************************************************************************* // 変更後の mylaplacianFoam.C ファイルです. 𝑑 𝑑𝑥 𝑘 𝑑𝑇 𝑑𝑥 = 0 を離散化して解く部分です. 各セル中心の X 座標と そこでの温度 T を 書き出します. 変更後
  30. 30. 30 作業3:createFields.H の変更 Info<< "Reading field T¥n" << endl; volScalarField T ( IOobject ( "T", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); Info<< "Reading transportProperties¥n" << endl; IOdictionary transportProperties ( IOobject ( "transportProperties", runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE ) ); Info<< "Reading diffusivity DT¥n" << endl; dimensionedScalar DT ( transportProperties.lookup("DT") ); createFields.H の内容(下記)を次ページのように変更します. 変更前
  31. 31. 31 作業3:createFields.H の変更 Info<< "Reading field T¥n" << endl; volScalarField T ( IOobject ( "T", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); Info<< "Reading transportProperties¥n" << endl; IOdictionary transportProperties ( IOobject ( "transportProperties", runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE ) ); Info<< "Reading diffusivity k¥n" << endl; dimensionedScalar k ( transportProperties.lookup(“k") ); 初期・境界条件を ファイルから読み 込み,変数Tを定 義しています. 熱伝導率 k を transportProperties ファイルから 読み込みます. 問題設定に合わせて, 記号を DT から k に 変更しています. 変更後の createFields.H ファイルです. 変更後
  32. 32. 32 作業4:確認計算 作業が半分終了したので,ここで確認計算をしてみましょう!  計算実行に必要なファイルを下記 URL にアップロードしてあります. https://www.dropbox.com/s/lbjd9r6zkmz5j9e/OpenFOAM_Practice1_20140316.zip  ダウンロードしたファイルを解凍すると,2つのフォルダがあります. • mylaplacianFoam: これまでの作業で作成したソルバーです. • testCase1: 22ページの問題の計算条件を設定したケースです.
  33. 33. 33 作業4:確認計算  まず,mylaplacianFoam をコンパイルします.  計算を実行してみましょう! $ sol $ cd basic/mylaplacianFoam $ wmake ケースフォルダに移動します. $ cd testCase1 計算格子を作成します. $ blockMesh 作成したソルバーを実行します. $ mylaplacianFoam
  34. 34. 34 作業4:確認計算 Create time Create mesh for time = 0 Reading field T Reading transportProperties Reading diffusivity k Calculating temperature distribution DICPCG: Solving for T, Initial residual = 1, Final residual = 1.21266e-16, No Iterations 1 X = 0.05, T = 140 X = 0.15, T = 220 X = 0.25, T = 300 X = 0.35, T = 380 X = 0.45, T = 460 End 計算はすぐに終了し,ターミナル画面に次のような出力があります. セル中心の X 座標とそこでの温度 T の計算結果です. ターミナル画面への出力
  35. 35.  計算結果が解析解と一致しているのが確認できます. それでは次のページからソルバーを更に変更して, 係数行列を出力して確認してみましょう. 35 作業4:確認計算
  36. 36. 36 作業5:mylaplacianFoam.C の変更 mylaplacianFoam.C を下記のように変更します. #include "fvCFD.H“ #include "simpleMatrix.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createMesh.H" #include "createFields.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "¥nCalculating temperature distribution¥n" << endl; while (runTime.loop()) { fvScalarMatrix TEqn(fvm::laplacian(k, T)); TEqn.solve(); forAll(T, cellI) { Info<< "X = " << mesh.C()[cellI].component(vector::X) << ", T = " << T[cellI] << endl; } #include "matrixWrite.H" runTime.writeAndEnd(); } Info<< "End¥n" << endl; return 0; } // ************************************************************************* // 赤字の2行を追加します.
  37. 37. 37 作業6:matrixWrite.H ファイルの作成 matrixWrite.H の内容は下記の通りです(あと2ページ続きます). // Investigate the Coefficient Matrix label Nc = mesh.nCells(); //Total number of cells simpleMatrix<scalar> A(Nc); //Coefficient matrix // Initialization of matrix for(label i=0; i<Nc; i++) { A.source()[i] = 0.0; for(label j=0; j<Nc; j++) { A[i][j] = 0.0; } } 行列Aを作成して,初期化しています. matrixWrite.H Part1
  38. 38. 38 作業6:matrixWrite.H ファイルの作成 // Assigning diagonal coefficients for(label i=0; i<Nc; i++) { A[i][i] = TEqn.diag()[i]; } // Assigning off-diagonal coefficients for(label faceI=0; faceI<TEqn.lduAddr().lowerAddr().size(); faceI++) { label l = TEqn.lduAddr().lowerAddr()[faceI]; label u = TEqn.lduAddr().upperAddr()[faceI]; A[l][u] = TEqn.upper()[faceI]; A[u][l] = TEqn.upper()[faceI]; } // Assigning contribution from BC forAll(T.boundaryField(), patchI) { const fvPatch &pp = T.boundaryField()[patchI].patch(); forAll(pp, faceI) { label cellI = pp.faceCells()[faceI]; A[cellI][cellI] += TEqn.internalCoeffs()[patchI][faceI]; A.source()[cellI] += TEqn.boundaryCoeffs()[patchI][faceI]; } } matrixWrite.H Part2行列Aに対角成分 を代入しています. 行列Aに非対角成分 を代入しています. 境界条件から対角成 分への寄与とソース 項への寄与分を行列 Aに代入しています.
  39. 39. 39 作業6:matrixWrite.H ファイルの作成 Info<< "¥n==Coefficient Matrix==" << endl; for(label i=0; i<Nc; i++) { for(label j=0; j<Nc; j++) { Info<< A[i][j] << " "; } Info<< A.source()[i] << endl; } //Info<< A << endl; Info<< "Solution: " << A.solve() << endl; 行列Aの各成分とソース項 (右辺ベクトル)の各成 分を書き出します. 『AT=右辺ベクトル』 を解いています. matrixWrite.H Part3 この解が,作業4の確認計算の解と一致すれば, fvScalarMatrix TEqn(fvm::laplacian(k, T)) の離散化で作成される係数行列を正しく行列Aで再 現できたと言えます.
  40. 40. 40 作業7:最終計算  まず,mylaplacianFoam をコンパイルしなおします.  計算を実行してみましょう! $ sol $ cd basic/mylaplacianFoam $ wclean $ wmake $ cd testCase1 $ mylaplacianFoam
  41. 41. 41 作業7:最終計算 計算を実行すると,ターミナル画面には次の出力があります. DICPCG: Solving for T, Initial residual = 1, Final residual = 1.21266e-16, No Iterations 1 X = 0.05, T = 140 X = 0.15, T = 220 X = 0.25, T = 300 X = 0.35, T = 380 X = 0.45, T = 460 ==Coefficient Matrix== -300 100 0 0 0 -20000 100 -200 100 0 0 0 0 100 -200 100 0 0 0 0 100 -200 100 0 0 0 0 100 -300 -100000 Solution: 5(140 220 300 380 460) End 無事解が一致しています! −300 100 0 0 0 100 −200 100 0 0 0 100 −200 100 0 0 0 100 −200 100 0 0 0 100 −300 𝑇1 𝑇2 𝑇3 𝑇4 𝑇5 = −20000 0 0 0 −100000 以上から,fvScalarMatrix TEqn(fvm::laplacian(k, T)) により作成される 係数行列と右辺ベクトルは以下のようになることがわかりました. 係数行列 右辺ベクトル
  42. 42. 42 Chapter 3 gdbOF ツールを使用して係数行列 を表示してみましょう.
  43. 43. 43 gdbOF について  gdbOF とは GDB(GNU Project Debugger)と共に用いて,OpenFOAM のアプリケー ションのデバッグ作業を手助けしてくれるツールです.  何ができるの? • 離散化により得られた係数行列の表示 や • セル中心値や境界値の表示 など他にもいろいろできるようです.詳細は,こちらの資料 [8] をご覧くだ さい.  ダウンロードサイト http://openfoamwiki.net/index.php/Contrib_gdbOF
  44. 44. 44 インストール 自分の環境(Ubuntu 12.04,OpenFOAM v2.3.0)では,以下の手順でインス トールができました. 1. (事前準備) OpenFOAM v2.3.0 をデバッグオプションでコンパイル 2. (事前準備) 必要なライブラリのインストール 3. ダウンロードしたファイル GdbOF_v1.01a.tar.gz を解凍 4. 解凍したフォルダ内のインストール用のスクリプトを実行 #- Optimised, debug, profiling: # WM_COMPILE_OPTION = Opt | Debug | Prof export WM_COMPILE_OPTION=Debug etc/bashrc ファイル (必要があれば)実行権限の付与 $ chmod +x installgdbOF.sh スクリプトを実行 $ ./installgdbOF.sh $ sudo apt-get install gawk python gdb
  45. 45. 45 何をするの? 再び Part2 で解いた定常熱伝導問題を題材にして mylaplacianFoam を gdb を使用してデバッグして, gdbOF により係数行列と右辺ベクトルを表示してみましょう!
  46. 46. 46 作業1,2  作業1:mylaplacianFoam をデバッグオプションでコンパイルし直します.  作業2:ケースフォルダに移動し,GDB を起動します. $ cd testCase1 $ gdb mylaplacianFoam GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Reading symbols from ~/platforms/linux64GccDPDebug/bin/mylaplacianFoam...done. (gdb) GDB が起動します.
  47. 47.  作業3:ブレークポイント(プログラムを強制的に一時停止させるポイン ト)を設定します. fvSclarMatrix.C ファイルの 170行目で一時停止させるという設定です. 47 作業3 (gdb) break fvScalarMatrix.C:170 No source file named fvScalarMatrix.C. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (fvScalarMatrix.C:170) pending. (gdb) 160 // Solver call 161 solverPerformance solverPerf = lduMatrix::solver::New 162 ( 163 psi.name(), 164 *this, 165 boundaryCoeffs_, 166 internalCoeffs_, 167 psi.boundaryField().scalarInterfaces(), 168 solverControls 169 )->solve(psi.internalField(), totalSource); 170 171 if (solverPerformance::debug) 172 { 173 solverPerf.print(Info.masterStream(mesh().comm())); 174 } STOP!
  48. 48. 48 作業4  作業4:ソルバーを実行します. Breakpoint 1 (fvScalarMatrix.C:170) pending. (gdb) run ・・・ Reading diffusivity k Calculating temperature distribution Breakpoint 1, Foam::fvMatrix<double>::solveSegregated (this=0x7fffffffcaf0, solverControls=...) at fvMatrices/fvScalarMatrix/fvScalarMatrix.C:171 171 if (solverPerformance::debug) (gdb) 作業3で指定したブレークポイントでソルバーが停止します.
  49. 49. 49 作業5  作業5:係数行列をファイルに出力します. matrix.txt は出力先のファイル名なので,任意の名前で構いません. 成功すれば,このような出力があるはずです. Breakpoint 1, Foam::fvMatrix<double>::solveSegregated (this=0x7fffffffcaf0, solverControls=...) at fvMatrices/fvScalarMatrix/fvScalarMatrix.C:171 171 if (solverPerformance::debug) (gdb) pfvmatrixfull this matrix.txt Saved correctly! (gdb)
  50. 50. 50 作業6  作業6:ファイルの中身を見てみましょう. 𝐴00 𝐴01 𝐴02 𝐴03 𝐴04 𝐴10 𝐴11 𝐴12 𝐴13 𝐴14 𝐴20 𝐴21 𝐴22 𝐴23 𝐴24 𝐴30 𝐴31 𝐴32 𝐴33 𝐴34 𝐴40 𝐴41 𝐴42 𝐴43 𝐴44 (gdb) pfvmatrixfull this matrix.txt 1 1 3 3 とすると赤枠内のみファイルに出力されます. 小さな誤差はありますが,40ページと同じ係数行列が得られています. -300.0 100.0 0 0 0 100.0 -200.00000000000006 100.00000000000006 0 0 0 100.00000000000006 -200.0000000000001 100.00000000000006 0 0 0 100.00000000000006 -199.99999999999991 99.99999999999986 0 0 0 99.99999999999986 -300.00000000000057 係数行列の出力フォーマット
  51. 51. 51 作業7  作業7:右辺ベクトルを出力します. 小さな誤差はありますが,40ページと同じ右辺ベクトルが得られています. (gdb) p *totalSource.v_@5 $6 = {-19999.999999999996, 0, 0, 0, -100000.00000000036} コマンド中の5は要素数です. 係数行列 右辺ベクトル
  52. 52. 52 Chapter 4 各項の離散化について理解を深めましょう. これにより,fvSchemes ファイルの設定 の意味が理解できます.
  53. 53. 53 参考となる資料  OpenFOAM の Programmer’s Guide [9] の 2章  Jasak 博士の博士論文 [10] の 3章 を読めば,必要な情報はほとんど得られると思います.
  54. 54. 早速,非圧縮性流体の支配方程式を見てみましょう.  それぞれの項には名前がついています. それぞれの項の離散化の方法を見ていきましょう. 54 方程式の項の分類 𝜕𝒖 𝜕𝑡 + 𝒖 ∙ 𝛻 𝒖 = − 1 𝜌 𝛻𝑝 + 𝛻 ∙ 𝜈 𝛻𝒖 + 𝛻𝒖 𝑇 時間微分項 対流項 勾配項 ラプラシアン項 𝛻 ∙ 𝜈𝛻𝒖 + 𝛻 ∙ 𝜈 𝛻𝒖 𝑇 分解 発散項
  55. 55. 55 勾配項の離散化  ガウスの発散定理を使用します. 𝛻𝑝 𝑑𝑉 𝑉 = 𝑑𝑺 ∙ 𝑝 𝑆 = 𝑺 𝑓 ∙ 𝑝 𝑓 𝑓 𝑺 𝑓 P Nf 𝑝 𝑓 gradSchemes { grad(p) Gauss linear; } セル中心から補間した フェイスでの値 𝑝 𝑓 ガウスの発散定理 𝑝 𝑓 の補間スキーム linear は線形補間.
  56. 56. 56 勾配項の離散化|ソースコード 075 const labelUList& owner = mesh.owner(); 076 const labelUList& neighbour = mesh.neighbour(); 077 const vectorField& Sf = mesh.Sf(); 078 079 Field<GradType>& igGrad = gGrad; 080 const Field<Type>& issf = ssf; 081 082 forAll(owner, facei) 083 { 084 GradType Sfssf = Sf[facei]*issf[facei]; 085 086 igGrad[owner[facei]] += Sfssf; 087 igGrad[neighbour[facei]] -= Sfssf; 088 } 089 ①内部フェイスでループ • ①の部分で,内部フェイスをループし,各フェイスにおいて 𝑺 𝑓 𝜙 𝑓 を計算し,その値を そのフェイスを界面とするセルに加えています. • 087 行で負符号が付いているのは,neighbour セルに関しては,その外向きベクトル が面積ベクトル 𝑺 𝑓 の逆向きのためです(𝑺 𝑓 の向きは owner ⇒ neighbour セルと定 義されています). gaussGrad.C
  57. 57. 57 勾配項の離散化|ソースコード 090 forAll(mesh.boundary(), patchi) 091 { 092 const labelUList& pFaceCells = 093 mesh.boundary()[patchi].faceCells(); 094 095 const vectorField& pSf = mesh.Sf().boundaryField()[patchi]; 096 097 const fvsPatchField<Type>& pssf = ssf.boundaryField()[patchi]; 098 099 forAll(mesh.boundary()[patchi], facei) 100 { 101 igGrad[pFaceCells[facei]] += pSf[facei]*pssf[facei]; 102 } 103 } 104 105 igGrad /= mesh.V(); 106 107 gGrad.correctBoundaryConditions(); ②境界フェイスでループ 境界上のフェイスを界面に もつセルの番号のリスト • ②の部分で,境界フェイスに対して①と同様の計算をしています. • 境界上のフェイスの法線ベクトルはセル外向きなので,101 行では正の符号. • 105 行で各セルでの体積積分値をセル体積で除し,勾配を計算しています.
  58. 58. divSchemes { div(phi,k) Gauss upwind; } 58 対流項の離散化  ガウスの発散定理を使用します. 𝛻 ∙ 𝑼𝑘 𝑑𝑉 𝑉 = 𝑑𝑺 ∙ 𝑼𝑘 𝑆 = 𝑺 𝑓 ∙ 𝑼 𝑓 𝑘 𝑓 𝑓 = 𝐹𝑘 𝑓 𝑓 ガウスの発散定理 𝑺 𝑓 P Nf 𝑘 𝑓 セル中心から補間した フェイスでの値 𝑘 𝑓 𝑘 𝑓 の補間スキーム upwind:風上補間 流束 (flux) 場
  59. 59. 59 対流項の係数行列  補間スキームに “upwind” を使用した場合の係数行列を 見てみましょう. i ji j F>0 i:owner j:neighbour 𝑘𝑖 𝑘𝑗 ⋮ < 0 −𝐹 𝐹 0 upwind
  60. 60. 60 対流項の係数行列 i ji j F≦0 i:owner j:neighbour 𝑘𝑖 𝑘𝑗 ⋮ < 𝐹 0 0 −𝐹 upwind  補間スキームに “upwind” を使用した場合の係数行列を 見てみましょう.
  61. 61. 61 対流項の係数行列  補間の重み w = 1 (F > 0の場合),w = 0 (F ≦0の場合) と定義することで, F の符号に関係なく,係数行列の成分は次のように表現できます. i ji j 𝑘𝑖 𝑘𝑗 ⋮ < 1 − 𝑤 ∙ 𝐹 −𝑤 ∙ 𝐹 𝑤 ∙ 𝐹 upwind − 1 − 𝑤 ∙ 𝐹
  62. 62. 62 対流項の離散化|ソースコード 093 fvMatrix<Type>& fvm = tfvm(); 094 095 fvm.lower() = -weights.internalField()*faceFlux.internalField(); 096 fvm.upper() = fvm.lower() + faceFlux.internalField(); 097 fvm.negSumDiag(); 098 099 forAll(vf.boundaryField(), patchI) 100 { 101 const fvPatchField<Type>& psf = vf.boundaryField()[patchI]; 102 const fvsPatchScalarField& patchFlux = faceFlux.boundaryField()[patchI]; 103 const fvsPatchScalarField& pw = weights.boundaryField()[patchI]; 104 105 fvm.internalCoeffs()[patchI] = patchFlux*psf.valueInternalCoeffs(pw); 106 fvm.boundaryCoeffs()[patchI] = -patchFlux*psf.valueBoundaryCoeffs(pw); 107 } 108 109 if (tinterpScheme_().corrected()) 110 { 111 fvm += fvc::surfaceIntegrate(faceFlux*tinterpScheme_().correction(vf)); 112 } 113 114 return tfvm; gaussConvectionScheme.C ①内部フェイスでの離散化 ②境界上のフェイスでの離散化 ③補間の補正項の陽的な処理  upwind 以外の場合も同様にして,対流項の係数行列の各成分は,フェイス における流束 faceFlux と補間スキームの重み weights から以下のように計 算されます.
  63. 63.  例えば,fvSchemes ファイルにおいて “div(phi,k) Gauss upwind;” と設定した場合 には, • ”faceFlux” が “phi” を, • ”weights” が “upwind” 補間スキームで定義されている重みを, • ”tinterpScheme_()” が 補間スキーム “upwind” を それぞれ表します.  補正 (correction) を伴う補間スキームについては,111 行でその補正項を陽的に評価 しています.  例えば,“linearUpwind” スキームの場合は, 𝛻 ∙ 𝑼𝑘 𝑑𝑉 𝑉 = 𝐹𝑓 ∙ 𝑘 upstream cell + correction 𝑓 𝑓 = 𝐹𝑓 ∙ 𝑘 upstream cell + 𝐹𝑓 ∙ correction 𝑓 𝑓𝑓 63 対流項の離散化|ソースコード 109 if (tinterpScheme_().corrected()) 110 { 111 fvm += fvc::surfaceIntegrate(faceFlux*tinterpScheme_().correction(vf)); 112 } 陰的に処理 ⇒ 係数行列へ 陽的に処理 ⇒ ソース項 (右辺ベクトル)へ 111 行で 加えている項
  64. 64. 64 対流項の離散化|bounded オプション 詳細は次ページから見ていきます. OpenFOAM v2.2.0 Release Note
  65. 65. 65 対流項の離散化|bounded オプション 0067 template<class Type> 0068 tmp<fvMatrix<Type> > 0069 boundedConvectionScheme<Type>::fvmDiv 0070 ( 0071 const surfaceScalarField& faceFlux, 0072 const GeometricField<Type, fvPatchField, volMesh>& vf 0073 ) const 0074 { 0075 return 0076 scheme_().fvmDiv(faceFlux, vf) 0077 - fvm::Sp(fvc::surfaceIntegrate(faceFlux), vf); 0078 } boundedConvectionScheme.C divSchemes { div(phi,k) bounded Gauss upwind; } 𝛻 ∙ 𝑼𝑘 を 𝛻 ∙ 𝑼𝑘 − 𝛻 ∙ 𝑼 𝑘 と計算します. の場合
  66. 66. 66 対流項の離散化|bounded オプション  bounded オプションを使用した場合には,対流項は次のように離散化され ます. 𝛻 ∙ 𝑼𝑘 − 𝛻 ∙ 𝑼 𝑘 𝑑𝑉 𝑉 = 𝑑𝑺 ∙ 𝑼𝑘 𝑆 − 𝛻 ∙ 𝑼 𝑘 𝑑𝑉 𝑉 = 𝑺 𝑓 ∙ 𝑼 𝑓 𝑘 𝑓 𝑓 − 𝑉𝑝 ∙ 𝑺 𝑓 ∙ 𝑼 𝑓𝑓 𝑉𝑝 ∙ 𝑘 𝑝 = 𝐹𝑓 𝑘 𝑓 − 𝑘 𝑝 𝐹𝑓 𝑓𝑓 連続の式から,非圧縮流れでは 解の収束に伴って 0 に収束します. Sp (61ページ)surfaceIntegrate (62ページ)
  67. 67. 67 対流項の離散化|bounded オプション 0098 template<class Type> 0099 Foam::tmp<Foam::fvMatrix<Type> > 0100 Foam::fvm::Sp 0101 ( 0102 const DimensionedField<scalar, volMesh>& sp, 0103 const GeometricField<Type, fvPatchField, volMesh>& vf 0104 ) 0105 { 0106 const fvMesh& mesh = vf.mesh(); 0107 0108 tmp<fvMatrix<Type> > tfvm 0109 ( 0110 new fvMatrix<Type> 0111 ( 0112 vf, 0113 dimVol*sp.dimensions()*vf.dimensions() 0114 ) 0115 ); 0116 fvMatrix<Type>& fvm = tfvm(); 0117 0118 fvm.diag() += mesh.V()*sp.field(); 0119 0120 return tfvm; 0121 } fvmSup.C 係数行列の 対角成分に加えています. fvm::Sp(fvc::surfaceIntegrate(faceFlux), vf) の計算
  68. 68. 68 対流項の離散化|bounded オプション 0042 template<class Type> 0043 void surfaceIntegrate 0044 ( 0045 Field<Type>& ivf, 0046 const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf 0047 ) 0048 { 0049 const fvMesh& mesh = ssf.mesh(); 0050 0051 const labelUList& owner = mesh.owner(); 0052 const labelUList& neighbour = mesh.neighbour(); 0053 0054 const Field<Type>& issf = ssf; 0055 0056 forAll(owner, facei) 0057 { 0058 ivf[owner[facei]] += issf[facei]; 0059 ivf[neighbour[facei]] -= issf[facei]; 0060 } 0061 0062 forAll(mesh.boundary(), patchi) 0063 { 0064 const labelUList& pFaceCells = 0065 mesh.boundary()[patchi].faceCells(); 0066 0067 const fvsPatchField<Type>& pssf = ssf.boundaryField()[patchi]; 0068 0069 forAll(mesh.boundary()[patchi], facei) 0070 { 0071 ivf[pFaceCells[facei]] += pssf[facei]; 0072 } 0073 } 0074 0075 ivf /= mesh.V(); 0076 } 内部フェイスでループ 境界フェイスでループ fvcSurfaceIntegrate.C fvm::Sp(fvc::surfaceIntegrate(faceFlux), vf) の計算
  69. 69. 69 対流項の離散化|bounded オプションまとめ divSchemes { div(phi,k) Gauss upwind; } divSchemes { div(phi,k) bounded Gauss upwind; } 𝛻 ∙ 𝑼𝑘 𝛻 ∙ 𝑼𝑘 − 𝛻 ∙ 𝑼 𝑘
  70. 70. 70 ラプラシアン項の離散化  ガウスの発散定理を使用します. 𝛻 ∙ Γ𝛻𝜙 𝑑𝑉 𝑉 = 𝑑𝑺 ∙ Γ𝛻𝜙 𝑆 = Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 𝑓 フェイスの法線方向 𝑺 𝒇 の 𝜙 の勾配値 Γ𝑓 の補間スキーム laplacianSchemes { default Gauss linear corrected; } ガウスの発散定理
  71. 71. 71 ラプラシアン項の離散化 𝛻 ∙ Γ𝛻𝜙 𝑑𝑉 𝑉 = 𝑑𝑺 ∙ Γ𝛻𝜙 𝑆 = Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 𝑓 𝑺 𝑓 P N セル中心間を結ぶ線分が その間のフェイスと直交する場合 𝑺 𝑓 𝜙 𝑁 − 𝜙 𝑃 𝒅 簡単に離散化できます. が・・・
  72. 72. 72 ラプラシアン項の離散化 実際の計算では,前ページのような 理想的なメッシュは生成できず, ほとんどこちらのケースになります. この場合, 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 の評価には工夫が必要です. 𝑺 𝑓 P N • セル中心間を結んだ線分 PN と • フェイスの法線ベクトル とが平行にならない場合
  73. 73. 73 ラプラシアン項の離散化  フェイスの面積ベクトル 𝑺 𝑓 を分解 ⇒ 𝑺 𝑓 = ∆ + 𝒌 Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑓∆ ∙ 𝛻𝜙 𝑓 + Γ𝑓 𝒌 ∙ 𝛻𝜙 𝑓 • 右辺第一項: 陰的に処理 ⇒ 係数行列 • 右辺第二項: 陽的に処理 ⇒ ソース項 = Γ𝑓 ∆ 𝜙 𝑁 − 𝜙 𝑃 𝒅 + Γ𝑓 𝒌 ∙ 𝛻𝜙 𝑓 非直交補正
  74. 74. 74 ラプラシアン項の離散化 ∆= 𝑺 2 𝒅 ∙ 𝑺 𝒅𝑺 = ∆ + 𝒌 𝑺 ∙ 𝒌 = 0 OpenFOAMでは,Jasak [10] に紹介されている3つの手法の内の 『over-relaxed approach』により非直交補正を行っています. 𝜃
  75. 75. 75 ラプラシアン項の離散化|非直交補正の大きさのコントロール laplacianSchemes { default Gauss linear uncorrected; } Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑓 ∆ 𝜙 𝑁 − 𝜙 𝑃 𝒅 + Γ𝑓 𝒌 ∙ 𝛻𝜙 𝑓 laplacianSchemes { default Gauss linear corrected; } Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑓 ∆ 𝜙 𝑁 − 𝜙 𝑃 𝒅 + Γ𝑓 𝒌 ∙ 𝛻𝜙 𝑓
  76. 76. 76 ラプラシアン項の離散化|非直交補正の大きさのコントロール laplacianSchemes { default Gauss linear limited 𝝍; } 0 ≤ 𝜓 ≤ 1 Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑓 ∆ 𝜙 𝑁 − 𝜙 𝑃 𝒅 + Γ𝑓 𝒌 ∙ 𝛻𝜙 𝑓 ∙ 𝑙𝑖𝑚𝑖𝑡𝑒𝑟 𝜓 𝜓 = 0 0.333 0.5 1 uncorrected の場合と同じです. corrected の場合と同じです. Γ𝑓 𝒌 ∙ 𝛻𝜙 𝑓 ≤ 0.5 × ∆ 𝜙 𝑁 − 𝜙 𝑃 𝒅 Γ𝑓 𝒌 ∙ 𝛻𝜙 𝑓 ≤ ∆ 𝜙 𝑁 − 𝜙 𝑃 𝒅 corrected と uncorrected の 中間的な処理に なっています.
  77. 77. 77 ラプラシアン項の離散化|非直交補正の大きさのコントロール 0051 template<class Type> 0052 tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > 0053 limitedSnGrad<Type>::correction 0054 ( 0055 const GeometricField<Type, fvPatchField, volMesh>& vf 0056 ) const 0057 { 0058 const GeometricField<Type, fvsPatchField, surfaceMesh> corr 0059 ( 0060 correctedScheme_().correction(vf) 0061 ); 0062 0063 const surfaceScalarField limiter 0064 ( 0065 min 0066 ( 0067 limitCoeff_ 0068 *mag(snGradScheme<Type>::snGrad(vf, deltaCoeffs(vf), "SndGrad")) 0069 /( 0070 (1 - limitCoeff_)*mag(corr) 0071 + dimensionedScalar("small", corr.dimensions(), SMALL) 0072 ), 0073 dimensionedScalar("one", dimless, 1.0) 0074 ) 0075 ); 0076 0077 if (fv::debug) 0078 { 0079 Info<< "limitedSnGrad :: limiter min: " << min(limiter.internalField()) 0080 << " max: "<< max(limiter.internalField()) 0081 << " avg: " << average(limiter.internalField()) << endl; 0082 } 0083 0084 return limiter*corr; 0085 } correctedSnGrads.C の Foam::fv::correctedSnGrad <Foam::vector>::correction が呼ばれます.  limiter(𝜓) は以下の limiter に対応しています. 𝜓 の値
  78. 78. 78 ラプラシアン項の離散化 0042 template<class Type> 0043 Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > 0044 Foam::fv::correctedSnGrad<Type>::fullGradCorrection 0045 ( 0046 const GeometricField<Type, fvPatchField, volMesh>& vf 0047 ) const 0048 { 0049 const fvMesh& mesh = this->mesh(); 0050 0051 // construct GeometricField<Type, fvsPatchField, surfaceMesh> 0052 tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tssf = 0053 mesh.nonOrthCorrectionVectors() 0054 & linear<typename outerProduct<vector, Type>::type>(mesh).interpolate 0055 ( 0056 gradScheme<Type>::New 0057 ( 0058 mesh, 0059 mesh.gradScheme("grad(" + vf.name() + ')') 0060 )().grad(vf, "grad(" + vf.name() + ')') 0061 ); 0062 tssf().rename("snGradCorr(" + vf.name() + ')'); 0063 0064 return tssf; 0065 }  非直交補正中の 𝛻𝜙 𝑓 の補間には,線形補間が使用されます. correctedSnGrad.C
  79. 79. 79 発散項の離散化  ガウスの発散定理を使用します. 𝛻 ∙ 𝜈 𝛻𝒖 𝑇 𝑑𝑉 𝑉 = 𝑑𝑺 ∙ 𝜈 𝛻𝒖 𝑇 𝑆 = 𝑺 𝑓 ∙ 𝜈 𝛻𝒖 𝑇 𝑓 𝑓 divSchemes { div(nu*T(grad(U))) Gauss linear; } セル中心からフェイスへの 補間スキーム ガウスの発散定理
  80. 80. 80 ソース項の離散化 ソース項の離散化には,次の3つの方法を使用できます. 1 2 3 Programmer’s Guide P-34 vol*Field として陽的にソース項を 定義します.セル体積をかける必要は ありません. 詳細は,次ページをご覧ください. 詳細は,81ページをご覧ください.
  81. 81. 81 ソース項の離散化 0098 template<class Type> 0099 Foam::tmp<Foam::fvMatrix<Type> > 0100 Foam::fvm::Sp 0101 ( 0102 const DimensionedField<scalar, volMesh>& sp, 0103 const GeometricField<Type, fvPatchField, volMesh>& vf 0104 ) 0105 { 0106 const fvMesh& mesh = vf.mesh(); 0107 0108 tmp<fvMatrix<Type> > tfvm 0109 ( 0110 new fvMatrix<Type> 0111 ( 0112 vf, 0113 dimVol*sp.dimensions()*vf.dimensions() 0114 ) 0115 ); 0116 fvMatrix<Type>& fvm = tfvm(); 0117 0118 fvm.diag() += mesh.V()*sp.field(); 0119 0120 return tfvm; 0121 } fvmSup.C 2 𝜌𝜙 𝑑𝑉 𝑉 = 𝑉𝑃 𝜌 𝑃 𝜙 𝑃 ソース項を陰的に扱います. 係数行列の対角成分に加えています.
  82. 82. 82 ソース項の離散化 0190 template<class Type> 0191 Foam::tmp<Foam::fvMatrix<Type> > 0192 Foam::fvm::SuSp 0193 ( 0194 const DimensionedField<scalar, volMesh>& susp, 0195 const GeometricField<Type, fvPatchField, volMesh>& vf 0196 ) 0197 { 0198 const fvMesh& mesh = vf.mesh(); 0199 0200 tmp<fvMatrix<Type> > tfvm 0201 ( 0202 new fvMatrix<Type> 0203 ( 0204 vf, 0205 dimVol*susp.dimensions()*vf.dimensions() 0206 ) 0207 ); 0208 fvMatrix<Type>& fvm = tfvm(); 0209 0210 fvm.diag() += mesh.V()*max(susp.field(), scalar(0)); 0211 0212 fvm.source() -= mesh.V()*min(susp.field(), scalar(0)) 0213 *vf.internalField(); 0214 0215 return tfvm; 0216 } 3 fvmSup.C ソース項の処理を符号で 場合分けします. 𝜌𝜙 𝑑𝑉 𝑉 = 𝑉𝑃 𝜌 𝑃 𝜙 𝑃 𝝆 𝑷 > 𝟎 の場合: の場合と同様に陰的に処理2 𝝆 𝑷 < 𝟎 の場合: の場合と同様に陽的に処理1
  83. 83. 83 Chapter 5 境界条件 内部フェイスと異なり,境界フェイスにおける離散化では 境界条件ごとに異なる取り扱いが必要です. OpenFOAMでの実装を理解しましょう. 𝒅𝜙 𝑏 𝜙 𝑃
  84. 84. 84 境界条件の分類  境界条件は,大きく以下の4つのタイプに分類できます. • ディリクレ (Dirichlet) 境界条件,第1種境界条件 境界上で関数値そのものを規定します.𝒙を境界上の点,𝑡を時間として, 次式の条件で表されます. 𝜙 𝒙, 𝑡 = 𝑓 𝒙, 𝑡 • ノイマン (Neumann) 境界条件,第2種境界条件 境界上で関数の勾配(gradient)を規定します.𝒙を境界上の点,𝑡を時間, 𝒏を境界の法線方向の単位ベクトルとして,次式で表されます. 𝜕𝜙 𝜕𝒏 𝒙, 𝑡 = 𝑔 𝒙, 𝑡 • ロビン (Robin) 境界条件,第3種境界条件 上記の2つの条件を組み合わせた条件です. 𝛼 𝒙, 𝑡 𝜙 𝒙, 𝑡 + 𝛽 𝒙, 𝑡 𝜕𝜙 𝜕𝒏 𝒙, 𝑡 = ℎ 𝒙, 𝑡 • 周期境界条件 境界法線方向の𝜙の勾配
  85. 85. 85 対応する OpenFOAM の境界条件 定常 (Steady) 非定常 (Time-Dependent) ディリクレ条件 Dirichlet ノイマン条件 Neumann ロビン条件 Robin Not Implemented 周期境界条件 Periodic fixedValue uniformFixedValue fixedGradient uniformFixedGradient zeroGradient mixed cyclic 𝜙 𝒙 = 𝑓 𝒙 𝜙 𝒙, 𝑡 = 𝑓 𝒙, 𝑡 𝜕𝜙 𝜕𝒏 𝒙 = 𝑔 𝒙 𝜕𝜙 𝜕𝒏 𝒙, 𝑡 = 𝑔 𝒙, 𝑡 𝜕𝜙 𝜕𝒏 𝒙 = 0 𝛼 𝒙 𝜙 𝒙 + 𝛽 𝒙 𝜕𝜙 𝜕𝒏 𝒙 = ℎ 𝒙 cyclicAMI
  86. 86.  まず境界フェイスにおけるラプラシアンの離散化を考えます.  境界フェイスでは4章で学んだ非直交補正の処理は行われません. Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 𝜙 𝑏 − 𝜙 𝑃 𝒅 86 境界フェイスでのラプラシアンの離散化 境界フェイスにおけるラプラシアン流束 𝒅𝜙 𝑏 𝜙 𝑃 フェイス面積 𝑺 𝑏 (添え字の b は境界上の値の意味です.) 境界隣接セル
  87. 87. 87 境界フェイスでのラプラシアンの離散化|zeroGradient 境界条件  勾配0条件 (zeroGradient) の場合 Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 𝜙 𝑏 − 𝜙 𝑃 𝒅 = 𝟎 𝑎11 𝑎1𝑁 𝑎 𝑁1 𝑎 𝑁𝑁 𝜙1 𝜙2 ⋮ 𝜙 𝑁 = 𝑠1 𝑠2 ⋮ 𝑠 𝑁 =0 (勾配が 0 より) 係数行列の対角成分と 右辺ベクトルの両方に 対して寄与がありません. … … … …
  88. 88. 88 境界フェイスでのラプラシアンの離散化|fixedGradient 境界条件  一般的なノイマン条件 (fixedGradient) の場合 Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 𝜕𝜙 𝜕𝒏 𝑏 𝑎11 𝑎1𝑁 𝑎 𝑁1 𝑎 𝑁𝑁 𝜙1 𝜙2 ⋮ 𝜙 𝑁 = 𝑠1 𝑠2 ⋮ 𝑠 𝑁 境界条件でこの値を 規定しているので 既知の値 陽的に処理できるので, 係数行列の対角成分に 対しての寄与はありません. … … … …
  89. 89. 89 境界フェイスでのラプラシアンの離散化|fixedValue 境界条件  ディリクレ条件(fixedValue) の場合 Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 𝜙 𝑏 − 𝜙 𝑃 𝒅 𝑎11 𝑎1𝑁 𝑎 𝑁1 𝑎 𝑁𝑁 𝜙1 𝜙2 ⋮ 𝜙 𝑁 = 𝑠1 𝑠2 ⋮ 𝑠 𝑁 = Γ𝑏 𝑺 𝑏 −1 𝒅 𝜙 𝑃 + Γ𝑏 𝑺 𝑏 1 𝒅 𝜙 𝑏 係数行列の対角成分と 右辺ベクトルの両方に 対して寄与があります. … … … …
  90. 90.  ロビン条件(mixed) の場合 Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 𝜙 𝑏 − 𝜙 𝑃 𝒅 = Γ𝑏 𝑺 𝑏 −𝑓 𝒅 𝜙 𝑃 𝑎11 𝑎1𝑁 𝑎 𝑁1 𝑎 𝑁𝑁 𝜙1 𝜙2 ⋮ 𝜙 𝑁 = 𝑠1 𝑠2 ⋮ 𝑠 𝑁 90 境界フェイスでのラプラシアンの離散化|mixed 境界条件 +Γ𝑏 𝑺 𝑏 𝑓 ∙ 𝑟𝑒𝑓𝑉𝑎𝑙𝑢𝑒 + 1 − 𝑓 ∙ 𝑟𝑒𝑓𝐺𝑟𝑎𝑑 ∙ 𝒅 𝒅 … … … … 係数行列の対角成分と 右辺ベクトルの両方に 対して寄与があります.
  91. 91. 91 gradientInternalCoeffs と gradientBoundaryCoeffs  具体的に見てきたように,ラプラシアンを境界フェイスで離散化する際の • 係数行列の対角成分 • 右辺ベクトル への寄与はディリクレ,ノイマン,ロビン境界条件により異なります.  OpenFOAMではこの違いを取り扱うために, それぞれの境界条件のクラスごとに次の2つの関数が定義されています. • gradientInternalCoeffs() 係数行列の対角成分への寄与 • gradientBoundaryCoeffs() 右辺ベクトルへの寄与 次のスライドからOpenFOAMでの実装を見ていきましょう.
  92. 92. 92 境界フェイスでのラプラシアンの離散化|zeroGradient の実装 template<class Type> tmp<Field<Type> > zeroGradientFvPatchField<Type>::gradientInternalCoeffs() const { return tmp<Field<Type> > ( new Field<Type>(this->size(), pTraits<Type>::zero) ); } template<class Type> tmp<Field<Type> > zeroGradientFvPatchField<Type>::gradientBoundaryCoeffs() const { return tmp<Field<Type> > ( new Field<Type>(this->size(), pTraits<Type>::zero) ); } 係数行列の対角成分と 右辺ベクトルの両方に 対して寄与がありません. zeroGradientFvPatchField.C
  93. 93. 93 境界フェイスでのラプラシアンの離散化|fixedGradient の実装 template<class Type> tmp<Field<Type> > fixedGradientFvPatchField<Type>:: gradientInternalCoeffs() const { return tmp<Field<Type> > ( new Field<Type>(this->size(), pTraits<Type>::zero) ); } template<class Type> tmp<Field<Type> > fixedGradientFvPatchField<Type>:: gradientBoundaryCoeffs() const { return gradient(); } fixedGradientFvPatchField.C Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 𝜕𝜙 𝜕𝒏 𝑏 係数行列の対角成分 への寄与はありません. 右辺ベクトルへの 寄与があります.
  94. 94. 94 境界フェイスでのラプラシアンの離散化|fixedValue の実装 template<class Type> tmp<Field<Type> > fixedValueFvPatchField<Type>::gradientInternalCoeffs() const { return -pTraits<Type>::one*this->patch().deltaCoeffs(); } Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 −1 𝒅 𝜙 𝑃 + Γ𝑏 𝑺 𝑏 1 𝒅 𝜙 𝑏 template<class Type> tmp<Field<Type> > fixedValueFvPatchField<Type>::gradientBoundaryCoeffs() const { return this->patch().deltaCoeffs()*(*this); } 係数行列の対角成分と 右辺ベクトルの両方に 対して寄与があります. 境界フェイスにおいて, deltaCoeffs() は,フェイス中心点と隣接セル中心点間の距離の逆数を返します. fixedValueFvPatchField.C
  95. 95. 95 境界フェイスでのラプラシアンの離散化|mixed の実装 template<class Type> tmp<Field<Type> > mixedFvPatchField<Type>::gradientInternalCoeffs() const { return -Type(pTraits<Type>::one)*valueFraction_*this->patch().deltaCoeffs(); } template<class Type> tmp<Field<Type> > mixedFvPatchField<Type>::gradientBoundaryCoeffs() const { return valueFraction_*this->patch().deltaCoeffs()*refValue_ + (1.0 - valueFraction_)*refGrad_; } mixedFvPatchField.C Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 −𝑓 𝒅 𝜙 𝑃 +Γ𝑏 𝑺 𝑏 𝑓 ∙ 𝑟𝑒𝑓𝑉𝑎𝑙𝑢𝑒 + 1 − 𝑓 ∙ 𝑟𝑒𝑓𝐺𝑟𝑎𝑑 ∙ 𝒅 𝒅
  96. 96. 96 境界フェイスでのラプラシアンの離散化 forAll(vf.boundaryField(), patchi) { const fvPatchField<Type>& pvf = vf.boundaryField()[patchi]; const fvsPatchScalarField& pGamma = gammaMagSf.boundaryField()[patchi]; const fvsPatchScalarField& pDeltaCoeffs = deltaCoeffs.boundaryField()[patchi]; if (pvf.coupled()) { //省略 cyclic境界条件などの場合の処理 } else { fvm.internalCoeffs()[patchi] = pGamma*pvf.gradientInternalCoeffs(); fvm.boundaryCoeffs()[patchi] = -pGamma*pvf.gradientBoundaryCoeffs(); } }  ラプラシアンの離散化のコードを確認してみましょう. Γ𝑓 𝑺 𝑓 ∙ 𝛻𝜙 𝑓 = Γ𝑏 𝑺 𝑏 −1 𝒅 𝜙 𝑃 + Γ𝑏 𝑺 𝑏 1 𝒅 𝜙 𝑏 cyclic境界以外の境界での離散化 gaussLaplacianScheme.C
  97. 97. 97 境界フェイスでの対流項の離散化  続いて,対流項の離散化を見ていきます.  対流項は各セルで次のように離散化されることを第4章で学びました. 𝛻 ∙ 𝑼𝜙 𝑑𝑉 𝑉 = 𝐹𝜙 𝑓 𝑓  この式から,境界フェイスでは, 𝐹𝜙 𝑏 の評価が必要であることが分かります. 𝜙 𝑏 𝜙 𝑃
  98. 98. 98 境界フェイスでの対流項の離散化|zeroGradient 境界条件  勾配0条件 (zeroGradient) の場合 𝜙 𝑏 − 𝜙 𝑃 𝒅 = 0 → 𝜙 𝑏 = 𝜙 𝑃 → 𝐹𝜙 𝑏 = 𝐹𝜙 𝑃 𝑎11 𝑎1𝑁 𝑎 𝑁1 𝑎 𝑁𝑁 𝜙1 𝜙2 ⋮ 𝜙 𝑁 = 𝑠1 𝑠2 ⋮ 𝑠 𝑁 𝜙 𝑏 𝜙 𝑃 係数行列の対角成分 に加わります. セル中心値は未知数なので … … … …
  99. 99. 99 境界フェイスでの対流項の離散化|fixedGradient 境界条件  一般的なノイマン条件 (fixedGradient) を課した場合 𝜙 𝑏 − 𝜙 𝑃 𝒅 = 𝑔 𝑏 → 𝜙 𝑏 = 𝜙 𝑃 + 𝑔 𝑏 𝒅 𝑎11 𝑎1𝑁 𝑎 𝑁1 𝑎 𝑁𝑁 𝜙1 𝜙2 ⋮ 𝜙 𝑁 = 𝑠1 𝑠2 ⋮ 𝑠 𝑁 係数行列の対角成分 に加わります. セル中心値𝜙 𝑝は未知数なので … … … … → 𝐹𝜙 𝑏 = 𝐹𝜙 𝑃 + 𝐹𝑔 𝑏 𝒅 右辺ベクトル に加わります. 全て値が既知なので
  100. 100. 100 境界フェイスでの対流項の離散化|fixedValue 境界条件  ディリクレ条件(fixedValue) の場合 指定された境界値を使って単純に次式により評価できます. 𝐹𝜙 𝑏 𝑎11 𝑎1𝑁 𝑎 𝑁1 𝑎 𝑁𝑁 𝜙1 𝜙2 ⋮ 𝜙 𝑁 = 𝑠1 𝑠2 ⋮ 𝑠 𝑁 右辺ベクトル に加わります. 全て値が既知なので … … … …
  101. 101. 101 valueInternalCoeffs と valueBoundaryCoeffs  具体的に見てきたように,境界フェイスにおける対流項の流束からの • 係数行列の対角成分 • 右辺ベクトル への寄与は,ディリクレ,ノイマン,ロビン境界条件によって異なります.  OpenFOAMではこの違いを取り扱うために, それぞれの境界条件のクラスごとに次の2つの関数が定義されています. • valueInternalCoeffs() 係数行列の対角成分への寄与 • valueBoundaryCoeffs() 右辺ベクトルへの寄与 次のスライドからOpenFOAMでの実装を見ていきましょう.
  102. 102. 102 境界フェイスでの対流項の離散化|zeroGradient の実装 template<class Type> tmp<Field<Type> > zeroGradientFvPatchField<Type>::valueInternalCoeffs ( const tmp<scalarField>& ) const { return tmp<Field<Type> > ( new Field<Type>(this->size(), pTraits<Type>::one) ); } template<class Type> tmp<Field<Type> > zeroGradientFvPatchField<Type>::valueBoundaryCoeffs ( const tmp<scalarField>& ) const { return tmp<Field<Type> > ( new Field<Type>(this->size(), pTraits<Type>::zero) ); } zeroGradientFvPatchField.C 係数行列の対角成分 に加わります. 右辺ベクトルへの 寄与はありません. 𝐹𝜙 𝑏 = 𝐹𝜙 𝑃
  103. 103. template<class Type> tmp<Field<Type> > fixedGradientFvPatchField<Type>::valueInternalCoeffs ( const tmp<scalarField>& ) const { return tmp<Field<Type> >(new Field<Type>(this->size(), pTraits<Type>::one)); } template<class Type> tmp<Field<Type> > fixedGradientFvPatchField<Type>::valueBoundaryCoeffs ( const tmp<scalarField>& ) const { return gradient()/this->patch().deltaCoeffs(); } 103 境界フェイスでの対流項の離散化|fixedGradient の実装 𝐹𝜙 𝑏 = 𝐹𝜙 𝑃 + 𝐹𝑔 𝑏 𝒅 fixedGradientFvPatchField.C 係数行列の対角成分と 右辺ベクトルの両方に 対して寄与があります.
  104. 104. 104 境界フェイスでの対流項の離散化|fixedValue の実装 template<class Type> tmp<Field<Type> > fixedValueFvPatchField<Type>::valueInternalCoeffs ( const tmp<scalarField>& ) const { return tmp<Field<Type> > ( new Field<Type>(this->size(), pTraits<Type>::zero) ); } template<class Type> tmp<Field<Type> > fixedValueFvPatchField<Type>::valueBoundaryCoeffs ( const tmp<scalarField>& ) const { return *this; } fixedValueFvPatchField.C 境界値を返しています. 係数行列の対角成分 への寄与はありません.
  105. 105. 105 境界フェイスでの対流項の離散化  対流項の離散化のコードを確認してみます. 𝐹 𝜙 𝑏 forAll(vf.boundaryField(), patchI) { const fvPatchField<Type>& psf = vf.boundaryField()[patchI]; const fvsPatchScalarField& patchFlux = faceFlux.boundaryField()[patchI]; const fvsPatchScalarField& pw = weights.boundaryField()[patchI]; fvm.internalCoeffs()[patchI] = patchFlux*psf.valueInternalCoeffs(pw); fvm.boundaryCoeffs()[patchI] = -patchFlux*psf.valueBoundaryCoeffs(pw); } gaussConvectionScheme.C
  106. 106. 106 境界条件のクラスの実装について  これまで見てきたように,Gaussの発散定理を使用した場合には,境界隣接 セルの離散化に際して,境界フェイスにおける流束の評価が必要ですが, この評価方法が下記の境界条件のタイプにより異なります. • ディリクレ境界条件 • ノイマン境界条件 • ロビン境界条件  このように離散化で異なる取り扱いが必要になる基本的な境界条件のクラス (src/finiteVolume/fields/fvPatchFields/basic/)が実装されています. • ディリクレ境界条件: fixedValueFvPatchFieldクラス • ノイマン境界条件: fixedGradientFvPatchFieldクラス, zeroGradientFvPatchFieldクラス • ロビン境界条件: mixedFvPatchFieldクラス • その他  これらの基本となるクラスを継承した派生クラス (src/finiteVolume/fields/fvPatchFields/derived/)を生成して, より具体的な境界条件 (非定常など) を実装しています. • valueInternalCoeffs • valueBoundaryCoeffs • gradientInternalCoeffs • gradientBoundaryCoeffs 異なる
  107. 107. 107 Chapter 6 simpleFoam simpleFoam を教材にして,流体計算のながれを より詳細に見ていきましょう.
  108. 108. 108 simpleFoam について  simpleFoam とは • 定常非圧縮性流れ計算のためのソルバーです. • RANS乱流モデルを使用できます.  支配方程式 𝛻 ∙ 𝒖 𝒖 = −𝛻𝑝 + 𝛻 ∙ 𝜈 𝑒𝑓𝑓 𝛻𝒖 + 𝛻𝒖 𝑇 𝛻 ∙ 𝒖 = 0 + 乱流変数の輸送方程式(乱流モデルにより異なります) 流速 𝑚/𝑠 密度で割った圧力 𝑚2/𝑠2 渦動粘性係数と分子動粘性係数の和 𝑚2 /𝑠 運動方程式 連続の式
  109. 109. 109 対流項の表現  対流項をベクトルの成分で書き下すと 𝛻 ∙ 𝒖 𝒖 = 𝛻 ∙ 𝑢1 𝑢1 𝑢1 𝑢2 𝑢1 𝑢3 𝑢2 𝑢1 𝑢2 𝑢2 𝑢2 𝑢3 𝑢3 𝑢1 𝑢3 𝑢2 𝑢3 𝑢3 = 𝜕 𝑢1 𝑢1 𝜕𝑥1 + 𝜕 𝑢2 𝑢1 𝜕𝑥2 + 𝜕 𝑢3 𝑢1 𝜕𝑥3 𝜕 𝑢1 𝑢2 𝜕𝑥1 + 𝜕 𝑢2 𝑢2 𝜕𝑥2 + 𝜕 𝑢3 𝑢2 𝜕𝑥3 𝜕 𝑢1 𝑢3 𝜕𝑥1 + 𝜕 𝑢2 𝑢3 𝜕𝑥2 + 𝜕 𝑢3 𝑢3 𝜕𝑥3
  110. 110. 110 対流項の表現  対流項は次式のように式変形できます. 𝛻 ∙ 𝒖 𝒖 = 𝛻 ∙ 𝒖 𝒖 + 𝒖 ∙ 𝛻 𝒖  第4章で見た対流項の離散化の ”bounded” オプションを使用した場合には, 収束までの過程で,非保存形 (non-conservative form) の表現を使用する ことを意味します. 𝛻 ∙ 𝒖 𝒖 − 𝛻 ∙ 𝒖 𝒖 = 𝒖 ∙ 𝛻 𝒖  計算が収束して,連続の式が満たされれば,次式が成り立ちます. 𝛻 ∙ 𝒖 𝒖 = 𝒖 ∙ 𝛻 𝒖 “bounded” オプションを 使用した場合の対流項の表現 非保存形
  111. 111. 111 simpleFoam のソースコード  simpleFoam のソースコードの場所 $WM_PROJECT_DIR/applications/solvers/incompressible/simpleFoam  simpleFoam のソースファイル • simpleFoam.C:メイン処理をまとめたファイル • createFields.H:流速 U や圧力 p 等の変数を定義します. • UEqn.H:運動方程式を解きます. • pEqn.H:圧力ポアソン方程式を解きます.  “simpleFoam” の名前の由来にもなっている SIMPLE アルゴリズムの実装の 中核を担っている “UEqn.H” と “pEqn.H” のコードの詳細を見ていきましょ う.
  112. 112.  計算の流れに沿って,UEqn.H ファイルから見ていきます.  UEqn.H ファイルでは運動方程式を離散化して解きます. 次のページからより詳しく見ていきましょう. 112 UEqn.H|概要 1 // Momentum predictor 2 3 tmp<fvVectorMatrix> UEqn 4 ( 5 fvm::div(phi, U) 6 + turbulence->divDevReff(U) 7 == 8 fvOptions(U) 9 ); 10 11 UEqn().relax(); 12 13 fvOptions.constrain(UEqn()); 14 15 solve(UEqn() == -fvc::grad(p)); 16 17 fvOptions.correct(U); 運動方程式を離散化しています. 係数行列の不足緩和を行っています. 圧力勾配項を前の時間ステップの圧力から 計算して,流速場を計算します.
  113. 113. 113 UEqn.H|運動方程式の離散化  陰的に処理される項は係数行列を,陽的に処理される項は右辺ベクトルをそ れぞれ構成します. 𝛻 ∙ 𝒖 𝒖 − 𝛻 ∙ 𝒖 𝒖 = −𝛻𝑝 + 𝛻 ∙ 𝜈 𝑒𝑓𝑓 𝛻𝒖 + 𝛻𝒖 𝑇 𝐴11 𝐴1𝑁 𝐴 𝑁1 𝐴 𝑁𝑁 𝑢1𝑘 𝑢2𝑘 ⋮ 𝑢 𝑁𝑘 = 𝑠1𝑘 𝑠2𝑘 ⋮ 𝑠 𝑁𝑘  ここで,𝑢𝑖𝑘 および 𝑠𝑖𝑘 の1つ目の添え字 𝑖 はセル番号を,2つ目の添え字 𝑘 はベクトルの成分 𝑘 = 1, 2, 3 を表しています. 陰的処理 陽的処理 … … … … 非直交 補正
  114. 114. 114 UEqn.H|不足緩和(under relaxation)  離散化 (3~9行) により得られる方程式は,次式のように書き表せます. 𝐴 𝑃 𝒖 𝑃 + 𝐴 𝑁 𝒖 𝑁 𝑁 = 𝒔  11行目で行っている不足緩和は,係数行列の対角成分を大きくするための操 作です.これにより連立方程式が解きやすくなります. 𝐴 𝑃 𝛼 𝒖 𝑝 + 𝐴 𝑁 𝒖 𝑁 𝑁 = 𝒔 + 𝐴 𝑃 𝛼 − 𝐴 𝑃 𝒖 𝑃 0 これを少し整理すると, 𝐴 𝑃 𝛼 𝒖 𝑃 + 𝐴 𝑁 𝒖 𝑁 𝑁 = 𝒔 + 1 − 𝛼 𝛼 𝐴 𝑃 𝒖 𝑃 0 641 // ... then relax 642 D /= alpha; 671 // Finally add the relaxation contribution to the source. 672 S += (D - D0)*psi_.internalField(); fvMatrix.C 0 < 𝛼 < 1 なので,もともとの係数 𝐴 𝑝 よりも大きな値をとります. 1 2 𝛼:緩和係数 𝒖 𝑃 0 :前の時間ステップの解
  115. 115. 115 UEqn.H|不足緩和(under relaxation)  前ページの 式と 式の関係を見てみます. 𝐴 𝑃 𝒖 𝑃 + 1 − 𝛼 𝛼 𝐴 𝑃 𝒖 𝑃 + 𝐴 𝑁 𝒖 𝑁 𝑁 = 𝒔 + 1 − 𝛼 𝛼 𝐴 𝑃 𝒖 𝑃 0 式の両辺に,青枠の項が足された形になっているのが分かります.  この連立方程式を,反復解法により解いて収束解が得られる場合には,青枠 の項は同じ値に収束するので, 式と 式とで同じ解が得られることが 分かります.  以上説明してきた緩和係数 𝛼 の値は,fvSolution ファイルで設定します. 1 2 式を変形すると,2 1 1 2 relaxationFactors { equations { U 0.7; k 0.7; epsilon 0.7; } } 連立方程式を解くそれぞれの変数ごとに 緩和係数の値を設定します.
  116. 116. 116 UEqn.H|流速場の予測値  15行目で得られた解 𝒖 𝑃 ∗ について次の関係が成り立っています. 𝐴 𝑃 𝒖 𝑃 ∗ + 𝐴 𝑁 𝒖 𝑁 ∗ 𝑁 = 𝒔 − 𝑉𝑃 ∙ 𝛻 𝑝 𝑛−1 これを変形すると, 𝒖 𝑃 ∗ = 1 𝐴 𝑃 𝒔 − 𝐴 𝑁 𝒖 𝑁 ∗ 𝑁 − 𝑉𝑃 𝐴 𝑃 𝛻𝑝 𝑛−1 ここで,𝐴 𝑃,𝐴 𝑁,𝒔 をセル体積で除したものを再び同じ記号で表すと,次式の ように書き表せます. 𝒖 𝑃 ∗ = 1 𝐴 𝑃 𝒔 − 𝐴 𝑁 𝒖 𝑁 ∗ 𝑁 − 1 𝐴 𝑃 𝛻𝑝 𝑛−1 3 前のステップの圧力 流速場の予測値 セル体積
  117. 117. 117 この後の計算の流れ  SIMPLE 法では,流速場の修正量を次式から見積もります. 𝒖 𝑃 ′ = − 1 𝐴 𝑃 𝛻𝑝′  修正後の流速場 𝒖 𝑃 𝑛 が,連続の式を満たすように修正量を決定します. 𝛻 ∙ 𝒖 𝑃 𝑛 = 𝛻 ∙ 𝒖 𝑃 ∗ + 𝒖 𝑃 ′ = 0 𝛻 ∙ 1 𝐴 𝑃 𝒔 − 𝐴 𝑁 𝒖 𝑁 ∗ 𝑁 − 1 𝐴 𝑃 𝛻𝑝 𝑛−1 − 1 𝐴 𝑃 𝛻𝑝′ = 0 𝛻 ∙ 1 𝐴 𝑃 𝛻𝑝 𝑛 = 𝛻 ∙ 1 𝐴 𝑃 𝒔 − 𝐴 𝑁 𝒖 𝑁 ∗ 𝑁 4 5 3 と を使って変形4 6
  118. 118. 118 pEqn.H (Part1) 1 { 2 volScalarField rAU(1.0/UEqn().A()); 3 volVectorField HbyA("HbyA", U); 4 HbyA = rAU*UEqn().H(); 5 UEqn.clear(); 6 7 surfaceScalarField phiHbyA("phiHbyA", fvc::interpolate(HbyA) & mesh.Sf()); 8 9 fvOptions.makeRelative(phiHbyA); 10 11 adjustPhi(phiHbyA, U, p);  前のスライドの内容をどのように実装しているのか見ていきましょう. pEqn.H  2~4行目 𝒖 𝑃 ∗ = 1 𝐴 𝑃 𝒔 − 𝐴 𝑁 𝒖 𝑁 ∗ 𝑁 − 1 𝐴 𝑃 𝛻𝑝 𝑛−1 (再掲) 4行目で,HbyA という変数に代入しています. rAU UEqn().H() 3
  119. 119. 119 pEqn.H (Part1) |UEqn().A()  このスライドの赤字の部分の処理に対応して,UEqn().A() は係数行列の対 角成分をセル体積で割った値を返します. template<class Type> Foam::tmp<Foam::volScalarField> Foam::fvMatrix<Type>::A() const { tmp<volScalarField> tAphi ( new volScalarField ( IOobject ( "A("+psi_.name()+')', psi_.instance(), psi_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), psi_.mesh(), dimensions_/psi_.dimensions()/dimVol, zeroGradientFvPatchScalarField::typeName ) ); tAphi().internalField() = D()/psi_.mesh().V(); tAphi().correctBoundaryConditions(); return tAphi; } fvMatrix.C
  120. 120. 120 pEqn.H (Part1) |UEqn().H()  このスライドの赤字の部分の処理に対応して,UEqn().H() は係数行列の非 対角成分と右辺ベクトルをセル体積で割った値で計算されます. template<class Type> Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::fvMatrix<Type>::H() const { tmp<GeometricField<Type, fvPatchField, volMesh> > tHphi ( new GeometricField<Type, fvPatchField, volMesh> ( IOobject ( "H("+psi_.name()+')', psi_.instance(), psi_.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), psi_.mesh(), dimensions_/dimVol, zeroGradientFvPatchScalarField::typeName ) ); GeometricField<Type, fvPatchField, volMesh>& Hphi = tHphi(); (中略) Hphi.internalField() += lduMatrix::H(psi_.internalField()) + source_; addBoundarySource(Hphi.internalField()); Hphi.internalField() /= psi_.mesh().V(); Hphi.correctBoundaryConditions(); fvMatrix.C
  121. 121. 121 pEqn.H (Part1) |補足 1 // Momentum predictor 2 3 tmp<fvVectorMatrix> UEqn 4 ( 5 fvm::div(phi, U) 6 + turbulence->divDevReff(U) 7 == 8 fvOptions(U) 9 ); 10 11 UEqn().relax(); 12 13 fvOptions.constrain(UEqn()); 14 15 solve(UEqn() == -fvc::grad(p)); 16 17 fvOptions.correct(U);  方程式の離散化に際して,UEqn() (3~9行)の定義の方に圧力勾配項 -fvc::grad(p) を含めないことで,UEqn().H() はこの項を含まずに計算して います. -fvc::grad(p) を UEqn() の定義に含めていない
  122. 122. 122 pEqn.H (Part1)|体積流束 (volumetric flux) の計算  7行目:HbyA から体積流束を計算しています. fvc::interpolate(HbyA) & mesh.Sf()  11行目: どの境界でも圧力を規定していない場合に,計算領域に流入出する流量の収 支が満たされるように流束を修正します. 流量の収支 = massIn - fixedMassOut - massCorr * adjustableMassOut と書き表した時に,流量の収支が満たされるように adjustableMassOut を 調整します. ここで, • massIn:計算領域に流入する全流量 • fixedMassOut:流速が規定されている境界から流出する流量 • adjustableMassOut:流速が規定されていない境界から流出する流量 • massCorr = (massIn - fixedMassOut)/adjustableMassOut HbyA をセル中心からフェイスへ補間 フェイスの法線ベクトル (大きさ;フェイスの面積)
  123. 123. 123 pEqn.H (Part2)|概要 13 // Non-orthogonal pressure corrector loop 14 while (simple.correctNonOrthogonal()) 15 { 16 fvScalarMatrix pEqn 17 ( 18 fvm::laplacian(rAU, p) == fvc::div(phiHbyA) 19 ); 20 21 pEqn.setReference(pRefCell, pRefValue); 22 23 pEqn.solve(); 24 25 if (simple.finalNonOrthogonalIter()) 26 { 27 phi = phiHbyA - pEqn.flux(); 28 } 29 } pEqn.H 圧力に関するポアソン方程式 を解いて,連続の式を満たすように圧力を求 め,流束の修正を行っています.次のページで詳細を見ていきます. 6
  124. 124. 124 pEqn.H (Part2)|圧力ポアソン方程式の解法  16~19行目:圧力ポアソン方程式の離散化 離散化により得られる関係式 1 𝐴 𝑃 𝑓 ∆ 𝑝 𝑁 − 𝑝 𝑃 𝒅 + 1 𝐴 𝑃 𝑓 𝒌 ∙ 𝛻𝑝 𝑓 𝑓 = 𝑯 𝐴 𝑃 𝑓 ∙ 𝑺 𝑓 𝑓 両辺まとめると, 𝑯 𝐴 𝑃 𝑓 ∙ 𝑺 𝑓 − 1 𝐴 𝑃 𝑓 ∆ 𝑝 𝑁 − 𝑝 𝑃 𝒅 + 1 𝐴 𝑃 𝑓 𝒌 ∙ 𝛻𝑝 𝑓 = 0 𝑓  25~28行目:流束場の修正 フェイスにおける流束を phi = phiHbyA - pEqn.flux() と計算することで,上式より 𝑝ℎ𝑖𝑓 = 0 となり,連続の式を満たすことが分かります. phiHbyA pEqn.flux()
  125. 125.  メッシュの non-orthogonality が大きい場合には,非直交補正の処理をルー プで行います.  非直交補正のループの回数は,”fvSolution” ファイルに設定します.  ループで圧力値が更新されるのに伴い非直交補正の量が更新されます. 1 𝐴 𝑃 𝑓 ∆ 𝑝 𝑁 − 𝑝 𝑃 𝒅 + 1 𝐴 𝑃 𝑓 𝒌 ∙ 𝛻𝑝 𝑓 𝑓 = 𝑯 𝐴 𝑃 𝑓 ∙ 𝑺 𝑓 𝑓 125 pEqn.H (Part2)|非直交補正ループ 13 // Non-orthogonal pressure corrector loop 14 while (simple.correctNonOrthogonal()) (省略) 29 } SIMPLE { nNonOrthogonalCorrectors 5; }
  126. 126. 126 pEqn.H (Part3) 31 #include "continuityErrs.H" 32 33 // Explicitly relax pressure for momentum corrector 34 p.relax(); 35 36 // Momentum corrector 37 U = HbyA - rAU*fvc::grad(p); 38 U.correctBoundaryConditions(); 39 fvOptions.correct(U); 40 } pEqn.H  34行目:圧力場の不足緩和 SIMPLE法では,圧力の修正量 𝑝 𝑛 − 𝑝 𝑛−1 (𝑝 𝑛 : ポアソン方程式の解, 𝑝 𝑛−1 : 前のステップの解) が過大に評価され,計算の収束性に悪影響を与え る傾向があるため,それを防ぐために不足緩和が行われます. 𝑝 𝑛−1 + 𝛼 𝑝 𝑝 𝑛 − 𝑝 𝑛−1  緩和係数 𝛼 𝑝 の値は,fvSolution ファイルに設定します. relaxationFactors { fields { p 0.3; } }
  127. 127.  圧力場に対する不足緩和は次のコードで行われます. 127 pEqn.H (Part3)|圧力場の不足緩和 873 template<class Type, template<class> class PatchField, class GeoMesh> 874 void Foam::GeometricField<Type, PatchField, GeoMesh>::relax(const scalar alpha) 875 { 876 if (debug) 877 { 878 InfoIn 879 ( 880 "GeometricField<Type, PatchField, GeoMesh>::relax" 881 "(const scalar alpha)" 882 ) << "Relaxing" << endl << this->info() << " by " << alpha << endl; 883 } 884 885 operator==(prevIter() + alpha*(*this - prevIter())); 886 } GeometricField.C
  128. 128. 128 pEqn.H (Part3)|流速場の修正  37行目:流速場の修正 不足緩和を行った圧力場から勾配を計算して,流速場を修正します. 𝒖 𝑃 𝑛 = 1 𝐴 𝑃 𝒔 − 𝐴 𝑁 𝒖 𝑁 ∗ 𝑁 − 1 𝐴 𝑃 𝛻𝑝 𝑝 𝑛−1 + 𝛼 𝑝 𝑝 𝑛 − 𝑝 𝑛−1
  129. 129. 129 Chapter 7 運動方程式と連続の式を連立して1つの行列で解く pUCoupledFoam を探検していきます.
  130. 130.  pUCoupledFoam は,foam のバージョン3.1に実装されています.  foam のインストール方法はこちら  ソースコードのヘッダー部の説明を見てみましょう. 支配方程式は,simpleFoam の場合と同じですが,この解法が異なります. 130 pUCoupledFoam の概要 Application pUCoupledFoam Description Steady-state solver for incompressible, turbulent flow, with implicit coupling between pressure and velocity achieved by BlockLduMatrix Turbulence is in this version solved using the existing turbulence structure. Authors Klas Jareteg, Chalmers University of Technology, Vuko Vukcevic, FMENA Zagreb.
  131. 131. 131 pUCoupledFoam の参考資料  開発者 Klas Jareteg さんの資料 (pdf) • pUCoupledFoam の開発者自身による説明資料です. • OpenFOAMへの実装方法が詳しく説明されておりとても参考になります. 私のスライドも上記の資料を参考にしていますが,この資料に記載のない内 容までカバーできるように理解を深めていきたいと思います.
  132. 132. 132 pUCoupledFoam の森へ1歩1歩 足を踏み入れていきましょう!
  133. 133. 133 解ベクトル Up Info << "Creating field Up¥n" << endl; volVector4Field Up ( IOobject ( "Up", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh, dimensionedVector4("zero", dimless, vector4::zero) );  流速 𝑈 の3つの方向成分と圧力 𝑝 の計4成分をもつベクトルを vector4 タイプの変数で表します. 𝑈 𝑥, 𝑈 𝑌, 𝑈 𝑍, 𝑝 𝑇 4成分
  134. 134. 134 今年中にかたちになるように, 逐次更新していきます.
  135. 135. 135 参考文献 [1] http://www.claymath.org/millennium-problems (accessed 03/16/2014) [2] ファーツィガー,ペリッチ,『コンピュータによる流体力学』 [3] http://www.openfoam.org/features/numerical-method.php (accessed 03/16/2014) [4] http://www.geocities.jp/penguinitis2002/index.html (accessed 03/16/2014) [5] https://www.simonsfoundation.org/quanta/20140224-a-fluid-new-path-in- grand-math-challenge/ (accessed 03/16/2014) [6] http://www.math.kz/images/journal/2013-4/Otelbaev_N-S_21_12_2013.pdf (accessed 03/16/2014) [7] http://arxiv.org/pdf/1402.0290v2.pdf (accessed 03/16/2014)
  136. 136. 136 参考文献 [8] http://openfoamwiki.net/images/1/18/GdbOF-Manual.pdf (accessed 03/23/2014) [9] http://foam.sourceforge.net/docs/Guides-a4/ProgrammersGuide.pdf (accessed 03/23/2014) [10] http://www.h.jasak.dial.pipex.com/ (accessed 03/23/2014)
  137. 137. 137 付録
  138. 138. 138 解析的なアプローチ:最近の動向  Navier-Stokes 方程式の解の存在の証明に関しては,2014年に入ってから 多くのニュースがあります [5]. • カザフスタンの Mukhtarbay Otelbaev 教授が,1月に解の存在証明に成 功したと宣言した論文 [6] については現在世界中の数学者による検証中で すが,既に証明に問題があることが判明し,教授がその解決に取り組んで いるそうです. The most recent attempt to garner serious attention, by Mukhtarbay Otelbaev of the Eurasian National University in Astana, Kazakhstan, is still under review, but mathematicians have already uncovered significant problems with the proof, which Otelbaev is trying to solve [5]. • カリフォルニア大学の Terence Tao 教授が2月に論文 [7] を発表しました.
  139. 139. 139 This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/

×