いわて駐在研究日誌

OpenCAE、電子工作、R/C等、徒然なるままに

Adaptive Mesh Refinement(AMR) on OpenFOAM 3.0.x

AMRはDyMソルバーで利用可能。3Dメッシュのみ+Parallel計算可能。

interDyMFoamのチュートリアルに含まれているconstant/dynamicMeshDictでは以下の通りに記述されている。

dynamicFvMesh   dynamicRefineFvMesh;

dynamicRefineFvMeshCoeffs
{
    // How often to refine     refineの頻度(time step)
    refineInterval  1;
    // Field to be refinement on   refineの基準変数(volScalarしかできない?)
    field           alpha.water;
    // Refine field inbetween lower..upper  基準変数のrefine下限値/上限値(この範囲がrefineされる)
    lowerRefineLevel 0.001;
    upperRefineLevel 0.999;
    // If value < unrefineLevel unrefine  unrefine最大の値(通常は大きな値としておくと、自動的にunrefineも行われることになる)
    unrefineLevel   10;
    // Have slower than 2:1 refinement    refineのバッファー
    nBufferLayers   1;
    // Refine cells only up to maxRefinement levels   refineの最大追加レベル
    maxRefinement   2;
    // Stop refinement if maxCells reached  リファイン停止条件の最大セル
    maxCells        200000;

    // Flux field and corresponding velocity field. Fluxes on changed
    // faces get recalculated by interpolating the velocity. Use 'none'
    // on surfaceScalarFields that do not need to be reinterpolated.
    correctFluxes
    (
        (phi none)
        (nHatf none)
        (rhoPhi none)
        (ghf none)
    );
    // Write the refinement level as a volScalarField
    dumpLevel       true;
}

 

助成金申請

なかなか科研費があたらないので、助成金のほうで頑張って稼ごうと足掻いています。

本日2件提出しました。来月も2件提出予定です。

現状、

・企業さんの申請に協力する形で2件(@30弱)

・某M社、E社の助成金(@100, @65)

を提出して結果待ちで、来月〆切のものは、

・某S社、I社の助成金(@100、@200)

とちょっと額が大きいので頑張って書くべし。

Dakotaの並列計算機能について(その5)

Dakotaの並列計算機能について整理してみる。

計算機環境で整理すると、

1)マルチコアワークステーション1ノード向け

  • dakotaのinstanceは1つだけ起動(シリアル)
  • 例えばasynchrnous evaluation_concurrency 4 (4つ同時にeval.)を指定する。
  • 1個1個のevaluation(simulation)は、シリアルorパラレル可能ただし、パラレル計算はノード内のコア間に限定される
  • 16coreのノードであれば、asynchrnous evaluation_concurrency 4 で個々のevaluation を4並列とするとcoreをすべて使用して計算することになる。

2)マルチノードクラスタ向け(ただし各ノードは1~4coreと小規模な場合)

  • dakotaをmpirun -np 4 -host node0,node1,node2,node3 dakota hoge.inのように並列起動する
  • ただし、dakotaはMPI supportでビルドされていることが必要
  • evaluationはシリアル計算のみ可能(パラレル計算とするとmpiプロセスのバッティングが起こる)

3)マルチノードクラスタ向け(ただし各ノードは8core~とそれなりにまともなHPCの場合)

3-1)バッチファイルシステムが使用できる場合

  • dakotaを起動
  • dakotaからバッチファイルシステムにevaluationのキューを順次投入
  • 個々のevaluationはシリアルでもパラレルでも可能
  • ....ということで、あまり通常のバッチファイルシステムの使い方に変更はない。

3-2)バッチファイルシステムが使用できない(しない)場合

 

  • dakotaを起動
  • dakotaからevaluationする場合に、どのノードに投入するか決定する(このNode Placement Methodにはいくつかの方法がある)。
  • 個々のevaluationはシリアルでもパラレル(mpirun)でも可能だが、ノード跨ぎのパラレル計算はできない。
  • work_directory "runs/run"
    directory_tag
    directory_save で個々のevaluationフォルダは残す。

Node Placement Methodとしては、

  1. Compute list of relative nodes based on
    • Number of nodes in allocation
    • Number of MPI tasks per node
    • Number of MPI tasks per simulation run
    • evaluation number (obtain from e.g. file_tag)
  2. Then launch simulation with relative node list option (-host) or machinefile option (-machinefile)
  3. Use local_evaluation_scheduling static in an input file

とのことで、以前の記事のような感じで計算できる。  

ざっくりと再掲しておくと、

[snip]

APPLIC_PROCS=2  # 1 evaluationあたりのCore数


# Current Eval. Number
num=$(pwd | awk -F. '{print $NF}') # workdir名からEval.番号を取得

CONCURRENCY=4   # Dakotaのconcurrency(inputファイル中で指定した値)
PPN=16          # ノード当たりのcore数

# 剰余演算でjob番号と、OFで利用するcore数などからホスト番号を計算
applic_nodes=$( ( (APPLIC_PROCS+PPN-1) / PPN ) )
relative_node=$( ( (num - 1) % CONCURRENCY*APPLIC_PROCS / PPN ) )

### relativeノードが使える場合(MPIのバージョンによる)
node_list="+n${relative_node}"
for node_increment in $(seq 1 $( (applic_nodes - 1) ) ); do
  node_list="$node_list,+n$( (relative_node + node_increment) )"
done

### relativeノードが使えない場合は以下のように、relative番号から実際のホストを対応づける
if   [ $relative_node -eq 0 ]; then  
   node_list="ensis10"
elif [ $relative_node -eq 1 ]; then  
   node_list="ensis12"
elif [ $relative_node -eq 2 ]; then   
   node_list="ensis13"
else
   node_list="ensis14"
fi

###  evaluationの実行
mpirun -np $APPLIC_PROCS -host $node_list my_simulation

 

平成28年度開始しました。

年度初めのドタバタを終了し、なんとか毎日のリズムが出てきた。

昨年度は練習問題を一生懸命やっていたなぁというのが正直な所で、今年度はちゃんとアウトプットしていきたい。

研究リハビリ第1段として、昨秋にやっていたDakotaのRosenbrock関数(2D)の最適化で(min = 0 at (x1,x2)=(1,1))、ちょっとパラメータの追い込みをしてみる。長岡のY先生曰く、モデル関数でパラメータセットを指定したら、CFDでの本番ではあまりいじらないそうなので、その言にしたがってみる。

 

設定すべきパラメータはいくつかあるが、まずはMOGAのパラメータセットは共通として、Kriging近似曲面でのSURROGATE でのサンプル数samples = 50/100/200/300/400と変えてやってみる(surrogate_based_global)。ただし、最小値が3つあるので、最後の値になるようにx1,x2の配位を狭めてやってみる。

        initial_point             -3  -3   
        lower_bounds       -5   -5    
        upper_bounds      10   10   
        descriptors      'x1'  'x2' 

結果は、以下のとおりで、samples=100がなんか怪しいが200以上であれば良さそう。

samples, x1, x2, fmin, CPUs
 50, 1.0585147380, 1.1213159660,  3.4983678384e-3, 2.86341
100, 3.0855104598, 9.5452386907, 4.4111751971, 5.580
200, 0.96201007998, 0.92113517035, 3.3165860016e-3, 7.68196
300, 1.0214072634, 1.0472875769, 2.0701161290e-3, 10.9975
400, 1.0585147380, 1.1213159660, 3.4983678384e-3, 14.3596
moga, 1.0585147380,  1.1213159660, 3.4983678384e-3, 41.47

 

 

 

 

 

OpenCV3.1.0+VS2015+Win10Pro

前から気になっていたOpenCVをいじってみようということで、とりあえずWebカメラのついている家PC(Win10Pro x86_64)に環境構築をトライしてみる。OpenCV3.1.0が年末に公開され、VS2015にも対応したとのことなので、C++の勉強もかねてVS2015 C++での開発を考えよう。

1.VS2015のダウンロード・インストール

MSから無償公開されているVS2015 Community版をダウンロード・インストール(vs

_community_JPN.exeを落としてきてダブルクリックし、ネットインストールすることになる。カスタムでインストールすると26GBくらい必要と表示された)。なお、インストール時に標準ではC#しか選択されないようなので、カスタムインストールでC++も選択しておく。2016/1現在で、VS2015 Update1が導入される。導入後はPCを再起動しておく。

f:id:waku2005:20160109133434p:plain

f:id:waku2005:20160109133439p:plain

 f:id:waku2005:20160109075659p:plain

 2.OpenCV 3.1.0のダウンロード・インストール

 ここからWindows用のOpenCV for Windows (opencv-3.1.0.exe)をダウンロードする。Githubから落としてくると早いかも。SFはミラーサイトにいきわたっていない?

http://opencv.org/downloads.html

自己解凍ファイル(exe)形式になっているので、ダブルクリックすると、opencvフォルダに展開されるので、フォルダごと適当な場所に置いておく。

今回は、バージョンがわかるようにopencv-3.1.0にリネームして、C:\Users\waku\opencv-3.1.0としておいておく。

なお、OpenCV3.0からAll-in-oneのライブラリ(C:\Users\waku\opencv-3.1.0\build\x64\vc14\lib\opencv_world310(d).lib)になったので、個別のlibが欲しい場合(2系列のように)やstaticライブラリが欲しい場合は、cmakeをつかってrebuildする必要があるとのこと。

3.Windows環境変数の設定

VS2015用動的ライブラリが置かれている場所は「C:\Users\Waku\opencv-3.1.0\build\x64\vc14\bin」であるので、これをWindowsのシステム環境変数PATHに追記する。環境変数は、システムのプロパティから設定できる。

4.VS2015での環境設定

 VS2015では、プロジェクトがOpenCVを認識できるようにOpenCVの「includeフォルダ」と「libraryフォルダ」を以下のようにして設定する必要がある。

  • まず、ファイル>新規作成>プロジェクトをクリックして、Win32コンソールアプリケーションの新しいプロジェクト(ここではプロジェクト名をOpenCV_Testとし、場所はc:\users\waku\documents\visual studio 2015\Projects)を作成する。
  •  次に、ビルド>構成マネージャーをクリックして、アクティブソリューションプラットフォームを「x86」から「x64」に変更する。debug/releaseはdebugのままとする。
  • ソリューション名”OpenCV_test”を右クリック>プロパティ>構成プロパティ>C/C++>全般を選択し、右側に出てくる設定画面に「追加のインクルードディレクトリ」が一番上にあるので、C:\Users\waku\opencv-3.1.0\build\includeを設定する(その下のopencv/opencv2までは不要)。
  • 同様にソリューション名”OpenCV_test”を右クリック>プロパティ>構成プロパティ>リンカ―>全般を選択し、右側の設定画面の中ほどにある追加のライブラリディレクトリにC:\Users\waku\opencv-3.1.0\build\x64\vc14\libを設定する。
  • 同様にソリューション名”OpenCV_test”を右クリック>プロパティ>構成プロパティ>リンカ―>入力を選択し、一番側の設定画面の中ほどにある追 加のライブラリディレクトリにopencv_world310(d).libを追記する。
  • http://chichimotsu.hateblo.jp/entry/2014/11/28/212432を参考に、opencv_libs.hppを作成し、上記のincludeフォルダに入れておく。

5.テストCoding

http://www.arubeh.com/archives/1102

にあったサンプルコードを以下のようにしてみた。

なお、各プロジェクトのプロパティから、構成プロパティ>C/C++>コード生成>「ランタイムライブラリ」をdebug/releaseに応じて変更する必要があるそうな。

Static Link

  • debugモードの場合:「マルチスレッドdebug(/MTd)」
  • releaseモードの場合:「マルチスレッド(/MT)」

Dynamic Link

  • debugモードの場合:「マルチスレッドdebugDLL(/MTd)」
  • releaseモードの場合:「マルチスレッドDLL(/MT)」

#include "stdafx.h"

// Dynamic Linkの場合
#include <opencv2/opencv.hpp> // インクルードファイル指定
//#include <opencv_libs.hpp> // 静的リンクライブラリの指定 (不要)

// Static Linkの場合
//#include <opencv2/opencv.hpp>
//#define _OPENCV_BUILD_STATIC_
//#include "opencv_libs.hpp"

using namespace cv; // 名前空間の指定

int main()
{
    //width220, height150の画像を作成
    Mat src = Mat::zeros(150, 220, CV_8UC3);

    //赤色で画像にHello Worldを描く
    putText(src, "Hello World", Point(5, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 200), 2, CV_AA);

    //緑色で画像に線を描く
    line(src, Point(190, 25), Point(190, 45), Scalar(0, 200, 0), 3);

    //要素を直接操作し画像に点を描く
    for (int x = 188; x < 192; x++) {
        for (int y = 53; y < 57; y++) { // y座標
            for (int i = 0; i < 2; i++) { // i < 3にするとBGRすべての要素を200にする
                src.at<uchar>(Point(x * 3 + i, y)) = saturate_cast<uchar>(200);
            }
        }
    }

    //画像を表示
    imshow("", src);

    //ウインドウの表示時間(0はキーが押されるまで閉じない)
    waitKey(0);

    return 0;
}

 LINK : fatal error LNK1104: ファイル 'opencv_ts310d.lib' を開くことができません。となりエラーになる?

(以上、STOPです。Cmakeでビルドしなおせということか?)

 

(01/10追記)

いろいろ調べたところ、OpenCV3.1.0には個別のライブラリではなく、全部入りのopencv_world310(d).libだけがついてくるそうで、リンカの入力にこのライブラリを指定すればOK。また、

#include <opencv_libs.hpp>

のようなstatic libraryの指定も不要らしい..というか、そもそもstatic libraryがついてこないので、camekを使って自前でbuildしなければいけないらしい。

f:id:waku2005:20160110201223p:plain

blockMeshのmultiGrading 機能(2.3.x~)

blockMeshDGなんていうツールもあるが、ちょっと調べたら2.3.xから本家のblockMeshコマンドにmultiGrading機能が追加されていたとのことで調べてみた。

従来のblockMeshでは例えば矩形ダクト流れを計算するときに壁面にメッシュを寄せたい場合は、ブロックを分割して壁面側にgradingを近づける必要があったが、新しい機能では、その必要がないということらしい。

 

1)一様メッシュ

blocks
(
    hex (0 1 2 3 4 5 6 7) (100 40 40)
    simpleGrading (

                             1
                             1
                             1
                             )
);

f:id:waku2005:20151029201029p:plain

 

 

 

2)multiGrading

blocks
(
hex (0 1 2 3 4 5 6 7) (100 40 40)
    simpleGrading (

       1

       // (fraction of the block, fraction of the divisions, grading ratio)
        ( (0.2 0.3 10) (0.6 0.4 1) (0.2 0.3 0.1) )
        ( (0.2 0.3 10) (0.6 0.4 1) (0.2 0.3 0.1) )
      )
);

f:id:waku2005:20151029201239p:plain

上記の例だと、x方向は一様分割で、yおよびz方向は、3つのグレーディングセクションに分かれており(3つの括弧が対応)、それぞれの括弧内は以下のように指定する。

(ブロック全体に占める割合  セクションが占める分割数の割合 グレーディング比)

具体的には、

(0.2 0.3 10)・・・ブロックの2割をセクション化し、分割数40分割の3割を割り当てるとする。比率は10なのでだんだん大きくなるようにする

(0.6 0.4 1)・・・ブロックの6割部分(真ん中のセクション)は一様分割

(0.2 0.3 0.1)・・・ブロックの2割をセクション化し、分割数40の3割を割り当てる。比率は0.1なのでだんだん小さくなるようにする

※ なお、0.2とか0.3というのは割合を指定できればよく、内部で規格化されるので、必ずしも和が1でなくてもよい。

Dakotaの並列計算機能について(その4)

ちょっと時間が開いてしまった。

4ノードの「なんちゃってクラスタ」でdakota+OF並列計算したいときのやり方をまとめておく。

クラスタでの利用にはいくつか(計算したい内容に応じて)方法があるが、ここでは、

  • 個々の目的関数の評価はOpenFOAMの並列計算結果を用いる(したがって1個1個の目的関数の評価は計算負荷が大きい)
  • OFの計算は1個1個のノード内で実行する
  • とくにTorqueやSLURMなどのリソースマネージャー(job scheduler)は利用しない

という条件で考える。

①dakotaの設定(dakota input file)

dakotaのプロセス自体はserialで実行し、evaluation_concurrencyを実行したいノード数に合わせる。

ポイントは   local_evaluation_scheduling staticで、この設定により例えばjob 2の次はjob 6、job10、.....という風にjobの順番が固定で回ってくるようにできる。

[snip]

interface,  
###############
  fork
    asynchronous
    evaluation_concurrency = 4
    local_evaluation_scheduling static

[snip]

②dakotaの設定(OFのドライバーファイルrun_openfoam.sh)

OFのジョブを起動するためのドライバスクリプト中で(shスクリプト)、どのjobがどのノードにmpirunで投入されるかを決める。こんな感じです。

 

# Cuurent Job number
num=$(pwd | awk -F. '{print $NF}')     ←workdir名からjob番号を取得
#echo $num
# Dakota concurrency (be same setting in dakota input file)
CONCURRENCY=4
# Num. of Procs per node
PPN=4
# number of processors per application job
APPLIC_PROCS=4
# relative node on which the job should schedule (floor)
# this is the first of the node block for this job
relative_node=$*1 ←剰余演算でjob番号と、OFで利用するcore数などからホスト番号を計算
#echo $relative_node
# build a node list ←ホスト番号からノード名を設定
if   [ $relative_node -eq 0 ]; then  
   node_list="ensis10"
elif [ $relative_node -eq 1 ]; then  
   node_list="ensis12"
elif [ $relative_node -eq 2 ]; then   
   node_list="ensis13"
else
   node_list="ensis14"
fi
echo "Evaluation on" $node_list
#for node_increment in `seq 1 $*2`; do
#  node_list="$node_list,+n$*3"
#done


./Allrun $node_list $APPLIC_PROCS ←OFの起動スクリプトにノード名とcore数を引き渡す

※ OpenMPIのrelative host indexingの機能を使えば、ノード名を設定しなくてもよさそうだが、なぜかうまくいかないので力技で指定しています。

→OpenMPIのMLに投げたところどうもバグらしい。OpenMPI2.0になるまで待てということらしい。

※ Allrunもちゃんと書き換えて、sHMとかも投入ノードで実行するようにしたほうがよさそうです。今は、master兼computeノード(具体的にはensis10)で実行してしまってるので...。

※ mpirunはsshで実行できるようにしてあります。ここらへんの設定は前にも書きました。

*1: (num - 1) % CONCURRENCY * APPLIC_PROCS / PPN

*2:applic_nodes - 1

*3:relative_node + node_increment