Pythonを使ってTRNSYSでパラメトリックシミュレーション

このところ、Pythonづいております。以前書いたように、汎用のパッケージを使ってTRNSYSの計算結果を簡単に扱うことができます。他にも使えそうなツールや、もしかしてすでにTRNSYSがらみのツールがあったりするんじゃないかと、ググってみたらありました。

PyBPS A parametric simulation manager for building performance simulation projects

pybps 0.1.2
pybps 0.1.2

シミュレーション実行の他、パラメトリック処理やプリ、ポストプロセスへも対応しているようです。Pythonのパッケージを組み合わせると、いろいろ処理ができそうです。

並列実行も対応しているようなので、大量に計算が必要なプロジェクトには良いかもしれません。 しかし、これPython2.7で書いているのか。。。(3.xだったら良かったのに)

TRNSYSで昼光シミュレーション?

Githubをぶらぶらと眺めていたら、RadianceとTRNSYSを使った昼光シミュレーションのコンポーネントを見つけました。(試してないけどね)

EURAC-EEBgroup/TypeDLT-for-TRNSYS

TypeDLT for TRNSYS
TypeDLT for TRNSYS

User GuideによるとRadianceの他、WINDOW7.3(Windowsじゃないですよ、LBNLのWINDOWです)、SketchUp、それにPerlの環境も必要になるようです。気軽に試す感じではないですが、昼光利用を検討される向きには面白いツールかも知れません。

個人的にはC/C++で書かれたコンポーネントらしいので、そっちの方が気になる。。。(C/C++サンプル少ないからねー、ってソースコード読んでみたらgccで書いてあるっぽいんで、これはこれで珍しい。)

TRNSYSの出力をPythonでグラフ化する

近頃、思うところがあってPython(オープンソースのスクリプト言語)を試しています。 TRNSYSで計算した結果をグラフで欲しいケースってありますよね?画面表示としてはType65がありますが、報告書など印刷物にはもう少しきれいなグラフが欲しいところ。そういう場合、Excelで加工してグラフ化するなどが定番ですが、もうちょっと簡単にできないものかなと。(いや、Excelでも十分簡単だと思うんですが、繰り返し、繰り返し作業するときはプログラムでサクッと処理できないものかと思うわけですよ)

というわけでPythonでTRNSYSの出力(CSV)の読み込みとグラフ処理を試してみました。 Pythonの仕組みとか詳しい話は省略して、読み込み処理してみたのがこちら。

CSVを読み込んで表示
CSVを読み込んで表示

TRNSYSのExamplesBegin.tpfの出力ファイルを読み込んで、一部を切り出して表形式で出力しています。画面上部に見えるのがスクリプトの部分ですが、ほんの数行です。ライブラリの宣言を除けばたったの2行です。(おお、グレイト!) つづいて、グラフを描いていて見ます。

こちらも、たった2行のスクリプト!しかも特に設定もしていないのに、デフォルトでそこそこきれいなグラフになります。 画像としてコピペもできるので、試しに貼りつけてみたのが下の図。

Pythonで描いたグラフ
Pythonで描いたグラフ

なんだろー、この簡単さ。たった4行でCSVの読み込みとグラフ化できるとか便利すぎる。グラフの表現とかいろいろ設定ありそうですが、面白そうなので今後試してみたいと思います。

作ってみようTRNSYSコンポーネント C/C++編(7) ヘッダーファイル・実践編

さてと、前回はTRNSYSの関数をC/C++コンポーネントから使う際の基本的な流れを解説しました。 今回は、もう少し具体的に掘り下げてみたいと思います。TRNSYSの関数と一口に言っていますが、ソースコードを眺めるとFunctionとして定義されている物と、Subroutineとして定義されている物の2種類あるのが分かります。 この2つ、ざっくり戻り値があるかないかの違いです。(C/C++から呼び出す際はどちらも関数として扱います)表にするとFunctionとSubroutineって戻り値があるか、ないか(void)の違いなんですよね。

戻り値の型引数の型
FunctionInteger,
Double Precision
なし、
Integer,
Double Precision
Subroutineなしなし、
Integer,
Double Precision

TRNSYSでは戻り値を返すgetIsVersionSigningTime()のように”get”で始まる関数はFunctionで、それ以外の関数はSubroutineとして定義されている事が多いようです。

C/C++の宣言

C/C++から呼び出す際の定義は以下の形式になります。ソースコードを調べて赤い文字の部分を適宜、型に合わせて変更します。

extern “C” __declspec(dllimport) 戻り値の型 _cdecl 関数名(引数の型* 引数の名前, 引数の型* 引数の名前);

例)SetTypeVersion() extern “C” __declspec(dllimport) void _cdecl SETTYPEVERSION(int* ver);

FOTRANとC/C++の値の型の対応は下表のようになります。

FORTRANC/C++
Integer,Integer(4)int
Real(8),Double Precisiondouble
Real(4)float

なお、引数はすべてポインタで宣言する点に注意して下さい。※

※2016/4/25 追記 FORTRAN側で引数にVALUE属性(値渡し)が指定されている場合を除く。(その場合は、通常の型で定義する必要があります)

別名の定義

関数に別名(Alias)を付けて場合は以下の形式です。この部分はなくても問題ありませんが、TRNDLL.DLLで公開されている関数名そのままだと、ソースコードが読みにくくなります。ここは多少手間でも定義しておくのがお勧めです。

#define     別名          関数名

例)SetTypeVersion()

#define setTypeVersion                    SETTYPEVERSION

ヘッダーファイルの準備

Simulation Studioからエクスポートされたプロジェクトでは予めTRNSYS16形式で最小限の関数が定義されてたヘッダーファイルを参照しています。

TRNSYS17形式のヘッダーファイル(こちらも最小限の関数が定義されています)も用意されているので、こちらへ差し替えて定義を追加するのが良いでしょう。

TRNSYS17形式のヘッダーファイルはC:Trnsys17SourceCodeTemplatesTRNSYS.h に用意されているので、このファイルをプロジェクトのフォルダへコピー、追加して登録します。

ヘッダーファイルを追加

ヘッダーファイル(TRNSYS.h)をプロジェクトのフォルダへコピーしたら、ソリューションエクスプローラーの「Header Files」フォルダで右クリック。表示されるメニューから[追加]-[既存の項目]を選んで、ヘッダーファイルを追加します。

ヘッダーファイルをプロジェクトへ追加
ヘッダーファイルをプロジェクトへ追加

後は適宜関数の定義を追加すればOK.

関数宣言を追加する
関数宣言を追加する

参考までに作成したサンプルをGithubで公開します。

プロフォルマ

C:¥TRNSYS17¥Studio¥Proformas¥My Components  へダウンロード、保存してください。

ソースコード

「Step7」フォルダの内容をC:¥TRNSYS17¥Compilers¥My Components へダウンロード、保存してください。

実行用のサンプルプロジェクト

C:¥TRNSYS17¥MyProjects¥MyComponent201 へダウンロード、保存してください。
ということで、C/C++は今回で終了!

—————————————————-

以下、このシリーズの目次

作ってみようTRNSYSコンポーネント C/C++編
(1) 基本情報
(2) ソースコードの生成
(3) ソースコードを読んでみよう
(4) Simulation Studioで実行してみよう
(5) コンポーネントが呼び出されるタイミング
(6) ヘッダーファイル・基本編
(7) ヘッダーファイル・実践編

作ってみようTRNSYSコンポーネント C/C++編(6) ヘッダーファイル

だいぶ間が空いてしまいましたが、「作ってみようTRNSYS.JPコンポーネント C/C++編」シリーズの続きです。

TRNSYS16 vs TRNSYS17

TRNSYS16までのコンポーネント開発では、INFO()配列のデータを使って処理の制御やデータの設定を行っていました。TRNSYS17以降では専用の関数が用意されたため、ソースコードの可読性が非常に高くなりました。ただし、残念ながらこれはFORTRANのみのサポートになります。

とはいえ関数自体はC/C++からも呼び出すことが可能です。ヘッダーファイルへ適切な宣言を行うことで利用可能です。(これTRNSYSに限らず、FOTRANのサブルーチンや関数をC/C++から利用するお話です。FOTRANの資産をC/C++でご利用になりたい向きも当てはまる話です) という訳で、ヘッダーファイルの作り方など解説してみたいと思います。

1.TRNSYSの関数名を取得する

公開されているTRNSYSの関数名を取得します。TRNSYSの関数はTRNDLL.DLL(C:TRNSYS17ExeTRNDLL.DLL)にすべて含まれていますが、FORTRANで利用する際とは異なる名前で公開されている関数が複数存在します。

C/C++から呼び出すため、関数名をTRNDLL.DLLより直接取得します。関数名の取り出しはVisual Studioに含まれる開発ツールを使用して行います。 はじめに、開発ツールを使用するための準備を行います。キーボーから[Win]+[R]をクリックして表示されるダイアログで”cmd”と入力してコマンドプロンプトを起動します。

ファイル名を指定して実行
ファイル名を指定して実行

コマンドプロンプトから以下のバッチファイルを実行して、開発ツールの利用環境を整えます。以下、Visual Studio 2013がインストールされたPCの作業例です。

> “C:Program Files (x86)Microsoft Visual Studio 12.0Common7Toolsvsvars32.bat”

つづいて、dumpbin.exeを使って、TRNDLL.DLLから関数名のリストを取得します。

> cd C:\TRNSYS17\Exe
> dumpbin /exports TRNDLL.DLL > trnsysfunctions.txt

これでtrnsysfunctions.txtに関数名がすべて書き出されました。

コマンドプロンプトで実行
コマンドプロンプトで実行

2.関数定義の確認

関数の引数や戻り値を調べるためFORTRANの関数定義を確認します。

TRNSYSのすべて関数のソースコードは「C:TRNSYS17SourceCodeKernel」フォルダに格納されています。これらのソースコードから、関数を定義しているソースコードを特定、定義内容を確認します。

ここでは、C/C++のソースコードの以下の箇所(コンポーネントのバージョン宣言処理の判定)に対応する関数getIsVersionSigningTime()を例に定義箇所を探してみます。(info配列と関数の対応はドキュメント「7.2. Updating TRNSYS 16 Components to the TRNSYS 17 Coding Standard」を参考にして調べます。)

//    SET THE VERSION INFORMATION FOR TRNSYS
if (info[6]== -2) ←この部分をTRNSYS17形式の関数にします。
{
info[11]=16;
// add additional initialisation code here, if any
return 1;
}

コマンドプロンプトから次のように入力して定義箇所を検索します。

> cd c:Trnsys17SourceCodeKernel

> findstr /i “getIsVersionSigningTime” .*.f90 | findstr /i “DLLEXPORT” .TrnsysFunctions.f90: !dec$ attributes dllexport :: getIsVersionSigningTime >

関数の定義を検索
関数の定義を検索

実行すると、関数を含むファイルの名前と定義されている行が表示されます。この例では「TrnsysFunctions.f90」に関数が含まれていることが分かります。 ソースコード調べると引数なし、戻り値はIntegerで定義されていることが分かります。

TrnsysFunctions.f90の関数定義
TrnsysFunctions.f90の関数定義

さらに、1.で作成したリストから公開されている関数名を確認します。メモ帳などでtrnsysfucntions.txtを開いて、”getIsVersionSigningTime” を検索してみると。。。

関数名
関数名

“TRNSYSFUNCTIONS_mp_GETISVERSIONSIGNINGTIME”という名前で公開されている事が分かります。(なんでこんな長い名前で公開されているかは謎ですが。。。)

3.ヘッダーファイルへ定義する

必要な情報が整ったので、いよいよ関数の定義を追加します。ここで目的の関数「getIsVersionSigningTime」の情報を整理すると。。。

  • 引数:なし
  • 戻り値:Integer
  • 名前:”TRNSYSFUNCTIONS_mp_GETISVERSIONSIGNINGTIME”

ここまで分かればC/C++の関数として定義できます。 具体的には、戻り値は整数(int)、引数はなし(void)として次のような定義になります。

extern "C" __declspec(dllimport) int _cdecl TRNSYSFUNCTIONS_mp_GETISVERSIONSIGNINGTIME(void);

しかし、これだと関数名が長くて、しかも大文字だらけで読みにくいので別名を定義します。

#define getIsVersionSigningTime            TRNSYSFUNCTIONS_mp_GETISVERSIONSIGNINGTIME

これでC/C++のソースコードから”getIsVersionSigningTime()”として呼び出すことができるようになります。次のようなイメージでソースコードを書き換える事ができるようになります。

//    SET THE VERSION INFORMATION FOR TRNSYS
if (getIsVersionSigningTime())
{
info[11]=16;
// add additional initialisation code here, if any
return 1;
}

でも、これたぶんエラーになります。TRNSYS17形式に書き換える場合、他の関数も同じように書き換える必要があります。この例ではinfo[11]へ値を設定していますが、これも関数に置き換える必要があります。 今回はヘッダーファイルを準備する基本的な流れと言うことで、たぶん

次回へつづく。

—————————————————-

以下、このシリーズの目次

作ってみようTRNSYSコンポーネント C/C++編
(1) 基本情報
(2) ソースコードの生成
(3) ソースコードを読んでみよう
(4) Simulation Studioで実行してみよう
(5) コンポーネントが呼び出されるタイミング
(6) ヘッダーファイル・基本編
(7) ヘッダーファイル・実践編

TRNSYSのトレーニングテキストを更新

TRNSYSのトレーニングテキストをTRNSYS3Dを使ったモノへ書き換えました。

以前から公開していたテキストではTRNBuildを使って建物モデルを作成していましたが、最近はTRNSYS3Dの利用が進んでいることもあり、TRNSYS3Dを使った内容へ書き換えました。

以下のサイトで公開中です。

GitHub/TRNSYS.JP

TRNSYS.JP/Docs/TRNSYS基本操作ガイド – 2室モデル TRNSYS3D.docx

リンク先の画面中央下の「View Raw」をクリックするとWord形式のファイルがダウンロードできます。

「View Raw」をクリックしてダウンロード

「View Raw」をクリックしてダウンロード

Typo: In word ‘sketchup’

新年度ですね。というわけでもないですが、SketchUpのカスタマイズアプリの作り方など調べています。
SketchUpはRubyを使ってSketchUpで図形を描いたり、データを取り出したりできるので、TRNSYS3Dのようなアプリケーションも作れるわけです。憶えたら、なにかと便利かなと始めたわけですが、試しはじめて躓いたのが、こちら。

Typo: In word ‘sketchup'
Typo: In word ‘sketchup’

RubyMineというIDEでコードを書き始めたら、いきなりこのメッセージ。sketchupのモジュールを宣言しているところで出ている。なんで?
パスの設定がまずくてファイルを見つけられない?でも実行するとエラーにはならない。はて???
しばらく考えて気がついたんだけど、これスペルチェッカーのワーニングっぽい。固有名詞の’sketchup’が辞書にないので表示している。
紛らわしい、エラーかと思ってしばらく悩んだ。無視して良さそうなので、終了。