OpenFOAMライブラリでプログラムを書く (5)関数オブジェクト

OpenFOAMライブラリでプログラムを書く (5)関数オブジェクト

OpenFOAMライブラリでプログラムを書く (5)関数オブジェクト

 OpenFOAMはC++で書かれたCFD(Computational Fluid Dynamics)ライブラリです。今回はOpenFOAMで利用できる関数オブジェクトについて解説します。





OpenFOAMで利用できる関数オブジェクト

 ソルバーを実行中に、さまざまな情報をログファイルに出力したい場合があります。このような機能を与えるのが関数オブジェクトです。OpenFOAMの関数オブジェクトは、ログファイルへのデータ出力だけではなく、サンプリングやユーティリティなど豊富な機能を提供しています。

 OpenFOAMでは、ユーザ自身が任意の機能を作成するためのcodedという名の関数オブジェクトを提供しています。今回は、このcodedを用いて、場の平均値を求める関数オブジェクトを作成します。

関数オブジェクトの設定方法

 関数オブジェクトを実行するには、contorolDictファイルのfunctions辞書内
#includeFunc指示子を用いて内容を記述した任意名のファイルを読み込む設定を行います。今回作成する関数オブジェクトを記述したファイル名をvolumeAverageとし、次のように記述します。

// in “controlDict” file
functions
{
    #includeFunc volumeAverage
}

coded関数オブジェクトの設定内容

 関数オブジェクトcodedの設定項目を以下に示します。



場の平均値を求める関数オブジェクト

 ここでは、場の平均流速を求める関数オブジェクトを作成します。interFoamを使用する場合を想定し、解析領域全域の平均流速に加えて、相1と相2の平均流速も算出します。

// 場の平均値を求める関数オブジェクト: volumeAverage

type	coded;
libs	(“libutilityFunctionObjects.so”);

name	volumeAverage;	   // 作成する関数オブジェクト名

Uname		U;	   // 流速の変数名
phase1Name	alpha.water;  // 相1の体積率の変数名
phase2Name	alpha.air;    // 相2の体積率の変数名

codeData
#{
    // メンバ変数の宣言
    word Uname_;
    word phase1Name_;
    word phase2Name_;
#};

codeRead
#{
    // このファイルの内容を読み込み、メンバ変数にセット
    dict.lookup(“Uname”) >> Uname_;
    dict.lookup(“phase1Name”) >> phase1Name_;
    dict.lookup(“phase2Name”) >> phase2Name_;
#};

codeExecute
#{
    // データベースから変数を呼び出す
    const volVectorField& U =		// 流速
        obr_.lookupObject<volVectorField>(Uname_);
    const volScalarField& alpha1 =	// 相1の体積率
        obr_.lookupObject<volScalarField>(phase1Name_);
    const volScalarField& alpha2 =	// 相2の体積率
        obr_.lookupObject<volScalarField>(phase2Name_);

    // 相1の領域内の体積分
    const scalar Umag1Vol =
        fvc::domainIntegrate(mag(U)*alpha1).value();
    // 相2の領域内の体積分
    const scalar Umag2Vol =
        fvc::domainIntegrate(mag(U)*alpha2).value();
    // 解析領域の体積分
    const scalar UmagAVol =
        fvc::domainIntegrate(mag(U)).value();

    // 相1の体積
    const scalar alpha1Vol =
        fvc::domainIntegrate(alpha1).value();
    // 相2の体積
    const scalar alpha2Vol =
        fvc::domainIntegrate(alpha2).value();
    // 解析領域の体積
    const scalar totalVol =
        gSum(alpha1.mesh().V().field());

    // 平均速度の算出
    scalar meanU1 =
        (alpha1Vol > 0.0) ? Umag1Vol/alpha1Vol : 0.0;
    scalar meanU2 =
        (alpha2Vol > 0.0) ? Umag2Vol/alpha2Vol : 0.0;
    scalar meanAU = UmagAVol/totalVol;
    
    if (Pstream::master())
    {
        // ログに出力
        Info<< “**** functionObject: volumeAverage ****\n”;
        Info<< “  Mean velocity U of “ << alpha1.name()
            << “\t : “ << meanU1 << nl;
        Info<< “  Mean velocity U of “ << alpha2.name()
            << “\t : “ << meanU2 << nl;
        Info<< “  Mean velocity U of both regions\t : “
            << meanAU << nl;
        Info<< “  Volume of “ << alpha1.name() << “\t : “
            << alpha1Vol << nl;
        Info<< “  Volume of “ << alpha2.name() << “\t : “
            << alpha2Vol << nl;
        Info<< “  Total volume\t\t : “ << totalVol << nl;
    }
#};

 はじめに、流速と各相の体積率の変数名をそれぞれキーワードUname、phase1Name、phase2Nameを用いて設定します。codeData辞書内に、これらの変数名を保存するメンバ変数を宣言し、codeRead辞書内でこのファイルで設定した変数名を各メンバ変数に代入します。

 次にcodeExecute辞書内で、相1、相2の各領域と解析領域全体で各変数の体積分を行います。この体積分値を解析領域内で各相が占める体積で割り、平均速度を算出します。

 最後に、算出した値をログに出力します。

 以上の例のように、このcoded関数オブジェクトを用いると、新たにクラスをユーザ自身で作成することなく、OpenFOAMが提供していない機能を作成することができます。



関連記事/関連ページ


OpenFOAM ライブラリでプログラムを書く (4) 入力ファイル
OpenFOAM ライブラリでプログラムを書く (6) コンテナクラス
OpenFOAM 解説書発刊のご案内