15
Fumiya Nozaki 最終更新日: 2015年6月6日 日本語版 Keywords: Block Matrix Coupled Solver foam-extend-3.1 チュートリアル blockCoupledSwirlTest

blockCoupledSwirlTestチュートリアル

Embed Size (px)

Citation preview

Fumiya Nozaki

最終更新日: 2015年6月6日

日本語版

Keywords: • Block Matrix • Coupled Solver

foam-extend-3.1 チュートリアル

blockCoupledSwirlTest

2

支配方程式

2つの温度 𝑇 と 𝑇𝑠 に関する方程式

𝛻 ∙ 𝑼𝑇 − 𝛻 𝐷𝑇𝛻𝑇 = 𝛼 𝑇𝑠 − 𝑇 −𝛻 𝐷𝑇𝑠𝛻𝑇𝑠 = 𝛼 𝑇 − 𝑇𝑠

流速 U は既知の結果を読み込んで使用

3

キーポイント

𝛻 ∙ 𝑼𝑇 − 𝛻 𝐷𝑇𝛻𝑇 = 𝛼 𝑇𝑠 − 𝑇 −𝛻 𝐷𝑇𝑠𝛻𝑇𝑠 = 𝛼 𝑇 − 𝑇𝑠

どのように解法があるでしょうか?

• 解法1 (Segregated):2つの方程式を別々に離散化し,順番に繰り返し解くことで,両方の方程式を満たす解を求める.

• 解法2 (Coupled):2つの方程式をまとめて1つの連立方程式に離散化し,これを解くことで,両方の方程式を満たす解を求める.

それぞれの方程式に,2つの未知変数 𝑇 と 𝑇𝑠 が含まれています.

blockCoupledScalarTransportFoam はこちらの解法

4

計算形状

outlet inlet

fixedWalls

inlet の温度分布

5

計算結果|𝑇 の分布

6

計算結果|𝑇𝑠 の分布

7

残差

反復数

残差履歴の比較 Coupled vs. Segregated

8

変数の定義|createFields.H

// Working coupled solution field Info<< "Creating field blockT¥n" << endl; volVector2Field blockT ( IOobject ( "blockT", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedVector2("zero", dimless, vector2::zero) ); { vector2Field& blockX = blockT.internalField(); blockMatrixTools::blockInsert(0, T.internalField(), blockX); blockMatrixTools::blockInsert(1, Ts.internalField(), blockX); }

2つの温度場 T と Ts (volScalarField) から, これらをまとめたベクトル場 blockT (volVector2Field) を作成しています.

初期値の代入

9

変数の定義|createFields.H

template<class BlockType> void blockInsert ( const direction dir, const scalarField& x, Field<BlockType>& blockX ) { forAll (x, i) { blockX[i](dir) = x[i]; } }

変数 blockT への値の代入を行っている blockInsert は次のように定義されています.

src/VectorN/finiteVolume/ blockMatrixTools/blockMatrixTools.C

T[0] Ts[0]

T[1] Ts[1]

⋮ ⋮

T[i] Ts[i]

blockT

dir=0 dir=1

i=0

i=1 ⋮ i 第 i 成分

10

方程式の離散化|blockCoupledScalarTransportFoam.C

fvScalarMatrix TEqn ( fvm::div(phi, T) - fvm::laplacian(DT, T) == alpha*Ts - fvm::Sp(alpha, T) ); TEqn.relax(); fvScalarMatrix TsEqn ( - fvm::laplacian(DTs, Ts) == alpha*T - fvm::Sp(alpha, Ts) ); TsEqn.relax();

まず,2ページに記載した2つの方程式を別々に離散化しています.

𝛻 ∙ 𝑼𝑇 − 𝛻 𝐷𝑇𝛻𝑇= 𝛼 𝑇𝑠 − 𝑇

−𝛻 𝐷𝑇𝑠𝛻𝑇𝑠 = 𝛼 𝑇 − 𝑇𝑠

11

方程式の離散化|blockCoupledScalarTransportFoam.C

// Prepare block system BlockLduMatrix<vector2> blockM(mesh); //- Transfer the coupled interface list for processor/cyclic/etc. // boundaries blockM.interfaces() = blockT.boundaryField().blockInterfaces(); // Grab block diagonal and set it to zero Field<tensor2>& d = blockM.diag().asSquare(); d = tensor2::zero; // Grab linear off-diagonal and set it to zero Field<vector2>& l = blockM.lower().asLinear(); Field<vector2>& u = blockM.upper().asLinear(); u = vector2::zero; l = vector2::zero; vector2Field& blockX = blockT.internalField(); vector2Field blockB(mesh.nCells(), vector2::zero);

ブロック係数行列 blockM,解ベクトル blockX,右辺ベクトル blockB 等の変数を 定義して,初期化しています.

12

方程式の離散化|blockCoupledScalarTransportFoam.C

//- Inset equations into block Matrix blockMatrixTools::insertEquation(0, TEqn, blockM, blockX, blockB); blockMatrixTools::insertEquation(1, TsEqn, blockM, blockX, blockB); //- Add off-diagonal terms and remove from block source forAll(d, i) { d[i](0, 1) = -alpha.value()*mesh.V()[i]; d[i](1, 0) = -alpha.value()*mesh.V()[i]; blockB[i][0] -= alpha.value()*blockX[i][1]*mesh.V()[i]; blockB[i][1] -= alpha.value()*blockX[i][0]*mesh.V()[i]; }

2つの係数行列からブロック係数行列を構成しています.

もともとの離散化では,陽的にソース項として扱っていた 赤字の項をブロック係数行列に追加して陰的に扱っています.

𝛻 ∙ 𝑼𝑇 − 𝛻 𝐷𝑇𝛻𝑇 = 𝛼 𝑇𝑠 − 𝑇

−𝛻 𝐷𝑇𝑠𝛻𝑇𝑠 = 𝛼 𝑇 − 𝑇𝑠

カップルして 1つの行列で解くから可能!

13

方程式の解法|blockCoupledScalarTransportFoam.C

//- Block coupled solver call BlockSolverPerformance<vector2> solverPerf = BlockLduSolver<vector2>::New ( blockT.name(), blockM, mesh.solutionDict().solver(blockT.name()) )->solve(blockX, blockB); solverPerf.print();

連立方程式を解きます.

14

解の取得|blockCoupledScalarTransportFoam.C

// Retrieve solution blockMatrixTools::blockRetrieve(0, T.internalField(), blockX); blockMatrixTools::blockRetrieve(1, Ts.internalField(), blockX); T.correctBoundaryConditions(); Ts.correctBoundaryConditions();

template<class BlockType> void blockRetrieve ( const direction dir, scalarField& x, const Field<BlockType>& blockX ) { forAll (x, i) { x[i] = blockX[i](dir); } }

src/VectorN/finiteVolume/ blockMatrixTools/blockMatrixTools.C

解ベクトル blockX から,変数 T と Ts の値を取り出し,境界値を更新しています.

15

次回の更新では, insertEquation を詳しく調べて,

ブロック係数行列の正体に迫ります.

template<class blockType, class matrixType> void insertEquation ( const label loc, fvMatrix<matrixType>& matrix, BlockLduMatrix<blockType>& A, Field<blockType>& x, Field<blockType>& b ) { insertDiagSource(loc, matrix, A, b); insertUpperLower(loc, matrix, A); updateCouplingCoeffs(loc, matrix, A); insertSolutionVector(loc, matrix.psi().internalField(), x); }