Equationでゼロ割対策(TRNSYS-USERSより)

ちょっとした計算に便利なEquationですが、値の組み合わせでゼロ割エラー(ゼロで除す割り算)が発生するケースがあります。

[TRNSYS-users] equation solver problem

この例ではType9から読み込んだ値を使って、A/Bのような式を計算しているとエラーが発生しています。エラーメッセージは、

“The TRNSYS Program attempted to evaluate an equation that has a division by zero”

ということなんですが、典型的なゼロ割エラーですね。読み込んでいる元データに0が含まれているようです。これはEquationに用意されている関数を使ったちょっとした工夫で対応できます。例えば、

A/(MAX(0.0001,B)

MAX関数を使って、受け取ったBの値と0.0001を比べて大きな方を使って計算を行っています。Bの値に0が来たら0.0001へ置き換えて計算するのでゼロ割エラーを避けることができます。(ただし、Bの値が正負両方の値が想定される場合は問題が発生するので、別の対策が必要です)

Equationの使い方についてはドキュメントの以下のセクションが参考になります。

2.7. Equations (基本的な操作方法)
6.3.9. The EQUATIONS Statement (用意されている関数等)

動作環境

以下の環境で動作を確認しています。
Windows10 Pro(64bit, 1803)
TRNSYS18.00.0019(64bit)

TRNSYSのEquationでゼロ割対策

2016-05-09_10h18_33

ちょっとした計算や判定処理になにかと便利なTRNSYSのEquaitonですが、計算内容によってはゼロ割(0による割り算)が発生することがあります。

TRNSYS-USERSを拾い読みしていたら簡単な対策が紹介されていました。

result = variable1/MAX(0.0001,variable2)

なるほど、シンプル。単純にMAX()で0を避けるだけ。そもそもvariable2が0になる原因をどう考えるかにもよりますが、無視しても構わない場合には簡単でいいです。

注意点としては、リンク先にも書いてありますが、variable2が負の値になることが想定されるようなケースでは使えません。

TRNSYSでスケジュール設定 x 3本勝負 (3) 条件判定

さて、前回はType14を使った設定例をご紹介しました。

シンプルなスケジュールであればEquationを使って同じような設定も可能です。

例えば、こんな感じ。

hour = mod(TIME,24)
OnOff = and(ge(hour,9),lt(hour,20))

この例では剰余演算mod()でTIMEを時刻(hour)に換算、その値を比較してOnOff状態を判定しています。

前回のType14に換えて、ここで計算したOnOffをType56へつなげば09:00-20:00の間だけ暖房がOnになります。

さて、ここまで紹介した例では、いずれもスケジュールが固定のケースでした。でも、実際計算する場合って、もうちょっと複雑な条件にしたいですよね?

例えば、暖かい日には暖房をOffにしたいというケースってないでしょうか?

そういう場合、既存のコンポーネントとEquationを組み合わせると簡単に条件を設定することができます。

Type14とEquationを組み合わせ条件判定

前回作成したType14のスケジュールとEquationで条件判定をしてみます。この例では、

  • 09:00-20:00 で暖房On
  • ただし、外気温が20℃以上ならOff

という条件で設定します。

コンポーネントのつなぎ方としては次のような構成をイメージしてください。

コンポーネントの準備

まずType14、こちらは前回そのままの設定です。ただし、直接Type56へつなぐのではなく、後述するEquationへつなぎます。

次はEquation。これで条件判定します。まず外気温とスケジュールの値が必要になるので、受け取るためのInputを追加します。

Tamb:外気温
Schedule:暖房のOn/Off

そして気象データリーダーからは外気温を受け取るように接続します。

さらにType14からはスケジュールを受け取るように接続します。

2016/5/24 追記
上の図では「Instantaneous value」から「Schedule」へつないでいますが、ここは「Average value」を使うのが適切なようです。

Equationで条件判定

さて、条件判定ですが、冒頭の例のようにand()関数で判定を行います。この関数は指定された2つの値が真であれば真の値(1)を返します。

スケジュールについてはOnOff状態をすでに受け取っていますので、外気温の状態を20℃未満であれば真(1)、20℃を超えていれば偽(0)とした値で処理します。

LowTemp = lt(Tamb,20)! Tambが20℃未満なら1,以上なら0
OnOff = and(LowTemp,Schedule) !LowTemp,Scheduleがどちらも1なら1

これで、外気温とスケジュールの判定処理が出来上がりました。後は、OnOffの値をType56へつなげばOKです。

この例のようにコンポーネントを組み合わせることで、条件判定を設定することができます。

つづかない。

2013/06/06追記

もう一回つづきます。

つづく。。。

TRNSYSでスケジュール設定 x 3本勝負 (1) Schedule
TRNSYSでスケジュール設定 x 3本勝負 (2) Input 
TRNSYSでスケジュール設定 x 3本勝負 (3) 条件判定
TRNSYSでスケジュール設定 x 3本勝負 (4) おまけ

TRNSYSのEquationで条件判定


Complementary Creative Commons Casio Calculator / Boaz Arad

TRNSYS-Usersを読んでいると、if-then-else処理の話題が出てました。

以下、メーリングリストからの抜粋ですが、TRNSYSで条件判定をやる場合、Equationを使って処理することになります。EquationにはGT(),LT()など、FORTRANでいう比較演算子に相当する関数が用意されています。これらを組み合わせて。。。

‘For example, let’s assume you would like to use the following “if-then-else”
statement:

if (Z>0) then
X=Y1
else
X=Y2
endif
The following equation will do the same:

X=GT(Z,0)*Y1+(1-GT(Z,0))*Y2

だいたいこんな感じで式を組み立てて判定します。
で、これを何に使うかというと、特定の条件でパラメータとか変えたい時です。
例えば、暖冷房機器の運転を冷房、暖房期間できっちりON/OFFしたい場合とかです。Equationを使って暖冷房期間の判定処理をして、冷房機に暖房が入ったり、逆に暖房機に冷房が入ったりといったことを避ける事ができます。

例)暖房期以外は冷房期 として処理する
暖房期 1/1-4/25, 10/21-12/31(1-2760, 7056-)
冷房期  4/26-10/20(暖房期以外)

これをEquationで表現すると、次のようになります。

HEATING = or(le(time,2760 ),ge(time,7056)) 
COOLING = not(HEATING) 

これでHEATING,COOLINGで、それぞれ暖房、冷房のOn/Off状態がつくれます。あとはType56のHeating TypeやCooling Typeで受け取って、暖房、冷房のPowerに渡してあげれば、暖房期間は暖房だけ、冷房期間は冷房だけというようなコントロールができます。
ちょっと慣れがいりますが、これを覚えると、いろんな場面で使えて重宝します。

2016/1/23 追記
1年以上の期間を計算すると、上記のやり方だと2年目はすべて暖房期間として判定されます。こまりますよねー。そういう場合は、mod()関数を使って、剰余として扱えば幸せになれます。
HOUR=mod(time,8760) 
HEATING = or(le(HOUR,2760 ),ge(HOUR,7056)) 
COOLING = not(HEATING) 

TRNSYSのEquationの便利な使い方

TRNSYSの小ネタです。

ちょっとした計算に便利なEquationですが、変数を扱う場合にも利用できます。

例としてグラフの表示を1年分から1週間分に変更してみます。

Type65を配置して、計算結果を出力すると、デフォルトではすべての結果をまとめて一画面にプロットします。

これを週単位で結果を表示したい場合、グラフのプロット数を指定してあげると、週単位で表示することができます。

Equationを使って設定する場合は、具体的には以下のような式を用意します。

nPlots = (STOP-START)/168.

※:START,STOPはTRNSYSが標準で用意している計算の開始、終了時刻を表す定数です。

 ここで設定したnPlotsは変数のように扱うことができるので、他のコンポーネントで直接、値として参照することができます。

で、実際に設定してみたのが以下の画面です。

Type65のParametersの”Number of plots per simulation”にnPlotsを直接指定しています。

 この状態で、再度シミュレーションを実行すると、今度はグラフが一週間単位で表示されれます。

Equationを使わずに、プロット数を直接指定しても構いません。でも、それだとシミュレーション時間が変わるようなケースでは、その都度入れ直しになります。

こういう場合には式で設定しておくと、変更なしで対応できます。

Simulation Studio上で、どこにもつながっていないEquationがあると、なにか気持ち悪い(悪くないですか?)場合は、Control Cardsに直接記述することも可能です。

こんな感じで記述すればOK。

どちらかという、個人的にはこちらの方がおススメです。Control Cardsに関連の強い値を設定する場合に、設定が解かりやすくなります。

例えば、以下の例ではタイムステップ(delt)も式として設定しています。この値を参照するのはControl Cardだけなので、独立したEquationとして定義するよりも関連性が分かりやすくなります。

TRNSYSのプログラム的な側面

TRNSYSでBuilding Projectを選らんで新規に作ったプロジェクトを見てたら、Equationの一部にこんな式が含まれていました。

IT_H_0_0 = Max(Input4,0)
IB_H_0_0 = Max(Input5,0)

受け取った入力値と”0″で最大値を取っている、つまり0以下の値は0にまとめちゃってるわけですが、何のために?

Input4と5を辿っていくと、どちらも日射量関係の値。普通に考えればマイナスの値はないはずなのに?なぞは深まるばかり。

計算精度

しばらく考えてて気が付いたんですが、TRNSYSもプログラムなので実数値の計算誤差はつきもの。小数点以下の小さい値で微妙な誤差が発生するときがまれにあります。プログラムを作った経験のある方だと、ああ、あれかと思える話ですが、理屈の上じゃマイナスにならないはずでも誤差がでることがあります。

よくある例はこんなの。0.1を10回足してみる。ちびっこでも解けそうな計算ですが、実際にEquationで書いてみると。。。

ten = 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1

答え:”+9.9999999999999989E-01″

(普通の十進表記に直すと”0.99999999999999989″)

てな具合に小数点以下10数桁目で微小な誤差がでます。

話を戻すと、普通はプログラムで誤差が出るようならキャップを掛けるような処理を入れるんですが、どうも用心のために入れているようです。

上記のようにEquationで計算するときも、同じようなケースがあてはまります。計算上変な値がでるんだけど、って時にはMaxを使って誤差分を修正する方法が役に立ちます。

(そもそも計算式が間違ってないことを確認してからの対策ですけどね)

ちなみに値が0から1になる計算であれば”Min(Max(val,0),1)“というようにまとめて書くと一回で済みます。