OpenModelicaのBuildingsライブラリで換気回路網計算を学ぶ_その3
概要
OpenModelicaでLBNLのBuildingsライブラリを使う。初心者なのでいろいろ教えて頂けるとありがたい。
前回Buildings.Airflow.Multizoneパッケージで風力換気の計算をしてみた。今回はその続きで気象データを読み込んで風向と風速が時間変化するときの換気量をみていきたい。
使用バージョン
-OpenModelica1.12.0 →Modelica標準ライブラリ3.2.2
-Buildings 5.1.0
作成するモデルの概要
前回作った風力換気の単室モデルに適当なスケジュールで発熱を与えて気象データを読み取って自然室温のようなものを計算する。外壁の熱貫流は無視しているので自然室温ではない。
べき乗則モデルの作成
前回と同様にBuildings.Airflow.Multizone.Examples.OneRoomのモデルをベースにするのでコピーしてくる。今回は外気側のボリュームを外部風向に合わせて風圧係数を計算できるBuildings.Fluid.Sources.Outside_CpLowRiseにしたいのだが、そのまま使うのも味気ないのでべき乗則で風速を補正して使うようにしてみる。気象データで得られる風速の計測高さと風圧係数を求めたときの風速の高さ(軒や屋根の高さ)は必ずしも一致しないので、気象データの風速をべき乗則などで補正してやる必要がある。気圧も高さが変わると補正が必要だと思うけれど、そもそも今は定数として標準大気圧を使っているので特に補正はしない。
今回使う気象データ(USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos)は風速計高さを調べても不明だったので30mを6mに換算してみる。energyplusの気象データの風速計の高さをどこで見るのかご存知の方がいれば教えて頂けるとありがたい。TMY3のマニュアルをみたりしたけれどよくわからず観測所の情報も緯度経度と高度はわかっても風速計高さにたどりつけなかった。アメダスの場合は気象庁の地域気象観測所一覧から確認できる。拡張アメダス標準気象データは風速計の高さを補正している場合があるので補正時と異なるべき指数を使いたい場合は注意が必要である。それから、元の風速計の高さが低くい場合は周辺の建物の影響を受けていたり、十分な高さの気象官署からデータを取るにしても検討地点から距離が離れすぎててたりと悩ましいことが少なくないのだけれどそこは割り切るしかないかもしれない。(よい検討方法が実はすでにあるかもしれないけれど。)
まずは前回のように修正したいモデルOutside_CpLowRiseをコピーしてくる。
変数として気象データの風速計高さhWea、風圧算出用の風速高さhCor、補正用のべき指数nCor、風圧算出用の風速vCorを加えてべき乗則で風速を補正して使用するように書き換える。元のモデルでは気象データから読み込む風速はvWinという変数に入れられている。
model Outside_CpLowRise "Boundary that takes weather data as an input and computes wind pressure for low-rise buildings" extends Buildings.Fluid.Sources.BaseClasses.Outside; parameter Modelica.SIunits.Height hWea "height in weathedata"; //追加部分 parameter Modelica.SIunits.Height hCor "height for Wind pressure coefficient"; //追加部分 parameter Real nCor "coefficient for power low"; //追加部分 Modelica.SIunits.Velocity vCor "Wind velocity at hCor"; //追加部分 (略) equation alpha = winDir - surOut; CpAct = Buildings.Airflow.Multizone.BaseClasses.windPressureLowRise(Cp0 = Cp0, incAng = alpha, G = G); vCor = vWin * ( ( hCor / hWea ) ^ nCor ); //追加部分 // pWin = 0.5 * CpAct * medium.d * vWin * vWin; //修正前コメントアウト pWin = 0.5 * CpAct * medium.d * vCor * vCor; //修正後 pTot = pWea + pWin; (略) end Outside_CpLowRise;
今回はこのような変更にしたけれど、connect(weaBus.winSpe, vWin);
の部分を消して、別途べき乗則用のモデルを用意して補正した風速をvWinにつないでもよいかもしれない。
できたら左のライブラリブラウザからドラッグ&ドロップしてきてoutNとoutSという名前をつけてやる。右クリックで横反転してやると見やすい。ここでは北壁を上の窓につなぐようにした。
ダブルクリックするとちゃんと設定にhWea、hCor、nCorが追加されているので30、6、0.28としてやる。べき指数は地表面の状態で変わる指数で、今回は平屋建物が立ち並ぶ郊外を想定して0.28にした。
風圧係数の関数について
風圧係数についてはOutside_CpLowRiseに組み込んである関数を使って算出するのだが。この関数はBuildings.Airflow.Multizone.BaseClasses.windPressureLowRiseにある関数で、BaseClassesと同じ場所にあるがfunctionである。
これを使わない場合の風圧係数は何らかの設計資料から似た形のものを引用したり、CFDから風圧係数を計算したり、場合によっては風洞実験をするなどの方法で風向別のデータを得ることができる。その場合は別途風向から風圧係数を算出するモデルを作るか、風向から風圧係数を事前に求めておいて時系列データとして読み込んでBuildings.Fluid.Sources.Outside_Cpに入力することになる。
今回使う気象データはチュートリアルのSpaceCooolingと同じものでは北風が0°で時計回りに東風が90°で南風が180°西風が270°となっており10°刻みで風向が定義されている。日本だと16風向で22.5°刻みのことが多いので不思議な感じがする。無風時はデータが空になっているらしいが今回はそのようなデータはなかった。ちなみに一般に風向の定義として南風は南から北へ向かって吹く風である。逆と間違えないようにしたい。
WindPressureLowRiseの関数はSwami and Chandra (1987) の論文によるものだ。 Cp0は風向が壁に正対するとき(南向きの壁に南風が吹いたとき)の風圧係数で一般的な低層の建物では0.6が推奨らしい。 sは(対象の壁の幅/対象の壁に隣接する壁の幅)である。隣接する壁の幅とは対象の壁に正対したときの建物の奥行き方向の長さになる。ここでは幅18m奥行き22mの建物と考えて0.81と入力してみる。 aziは壁の向きで南が0°、西が90°になっている。角度の単位はdegreeかradianか選べる他、東西南北についてはBuildings.Types.Azimuth.Nなどで指定してやることができる。これは次のように定義されているので単位はradianである。
within Buildings.Types; package Azimuth "List of possible constant values for surface azimuth" constant Modelica.SIunits.Angle E = -Modelica.Constants.pi/2 constant Modelica.SIunits.Angle N = Modelica.Constants.pi constant Modelica.SIunits.Angle S = 0 constant Modelica.SIunits.Angle W = +Modelica.Constants.pi/2 end Azimuth;
これでパラメータの設定ができた。nportは流体の入出力ポートでこれを1にしておく。CO2とか粉塵とかの計算はしないのでuse_C_inはfalseにする。それから、テキストビューで媒体の指定を追加してやる。
OneRoomTest.Outside_CpLowRise outN(redeclare package Medium = Medium,azi(displayUnit = "rad") = Buildings.Types.Azimuth.N,hCor = 6, hWea = 30, nCor = 0.28, nPorts = 1, s = 0.81)
気象データと発熱スケジュールの読み込み
気象データはBuildings.BoundaryConditions.WeatherData.ReaderTMY3を使う。湿球温度は特にいらないのでcomputeWetBulbTemperatureをfalseにし、filNamはライブラリにはじめからついているUSA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mosを使う。他のパラメータはデフォルトのままで大気圧はパラメーター固定値で他はファイルから、天空温度も使わないのでそのままにしている。
さらに換気による排熱の効果も見たいと思ったので室の内部発熱スケジュールを組み込んでみたいと思う。これはModelica標準ライブラリを使う。発熱スケジュールデータをModelica.Blocks.Sources.CombiTimeTable から読み込み、Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlowを経由してheatportとしてvolEasにつなぎこんでやる。PrescribedHeatFlowはデフォルトの設定のままでよいがインプットをそのまま出力するだけなのでalphaが0であることを確認する。
CombiTimeTableによる時系列データの入力は3種類あり、直接記述、ファイル読み込み、cのソースに書き込みができるようだがcのソースに書き込みの使い方がいまいちよくわからなかった。ファイルの読み込みはASCIIファイルのフォーマット以外にMATLABのフォーマットを使うことができるらしい。OMEdit上の設定は次のとおり。
tableOnFileをfalseにしたときはtableのところに直接テーブルを記述する。[0,0;1,2;2,0;3,2]のように各時刻のデータをカンマで区切り、時刻が変わるときにはセミコロンで区切る。毎時刻の一番初めのデータは時刻(秒)になるようにして時刻は単調増加(減少しない事)にしないといけない。基本的にテーブルに無い時刻のデータは線形補間で計算される。不連続に値を変動させたい場合は[0,0;1,0;1,2;2,0;3,2]などのようにすると1秒のところで不連続になる。この時刻では計算が2回行われるのだと思う。
tableOnFileをtrueにした場合はfileNameが”NoName”だとcのソースに書き込みになるらしい。"C:\OpenModelica1.12.0-64bit\lib\omlibrary\Modelica 3.2.2\Resources\Data\Tables"とかにあるusertab.cやらusertab.hやらにサンプルらしきものがある。
そしてファイル名を指定してやるとファイルの読み込みになる。同じところにtest.txtというサンプルファイルがある。読み込みファイルの形式としては
* 1行目に#1と記載する。(データ形式のバージョンを示す)
* double tab0(2,2)のようにデータ型(floatかdouble)、テーブル名(ここではtab0)、データの数(行数、列数)を示す。
* テーブルのデータをスペース、タブ、カンマ、セミコロンのいずれかで区切って記載していく。一列目には単位を秒として時刻を記述する。改行コードは特にその行のデータの終わりを意味しないので複数行に同じ時刻のデータを記載できる。
* 一つのファイルに複数のテーブルを記載できる。tableNameで読み込むテーブルを選択する。
今回はファイルを読み込んで使用するのでtableOnFileをtrueにし、tableはそのまま、tableNameは"heat"にして(ダブルクオーテーションを忘れないように)、fileNameは"C:/Users/Simulation/OModelica/heat.txt"とheat.txtを作成して指定する。verboseReadは読み込みのメッセージの出力設定なのでfalseでよいと思う。作成したファイルは次のとおり。9時から18時まで100Wの発熱を与えるようにする。時間が秒の単位になっていないがそれは別に設定する。テーブルが大きい場合はExcelでつくってcsvなどで書き出してやるとよいと思う。
#1 double heat(4,2) 0,0 9,100 18,0 24,0
設定の続きにもどる。columnsは読み込む列の番号を指定するのだと思うけれど使い方があまりよくわからなかった。今回はたぶん2列のデータなのでデフォルトで特に問題なかった。
smoothnessはテーブルに記載の無い時刻でのデータの補間の方法を指定する。デフォルトはLinearSegmentsで線形補間だがConstantSegmentsだとその前の時刻の値を保持することになるのでこれを指定する。
extrapolationはテーブルの時刻の外側のデータの取り扱いでデフォルトはLastTwoPointsで線形外挿だがPeriodicとして周期的にテーブルを使用する。これで1日分のスケジュールを毎日繰り返すようになる。
offsetは時刻以外のすべてのデータに加える値で0のままに、startTimeはすべての時刻に加える値で0のままにする。
timeScaleはすべての時刻に掛ける値でこれを3600にする。こうすることでスケジュールデータの時刻の単位を秒に変換できる。これで設定ができた。
時系列の換気量の計算
設定したファイルをつなげてやる。weaBusなどはインスタンスの名前がついていないことがあるので注意。
今回追加した部分の接続は以下の通り。
connect(colOutTop.port_b, outN.ports[1]); connect(colOutBot.port_a, outS.ports[1]); connect(weaDat.weaBus, outN.weaBus); connect(weaDat.weaBus, outS.weaBus); connect(combiTimeTable1.y[1], prescribedHeatFlow1.Q_flow); connect(prescribedHeatFlow1.port, volEas.heatPort);
計算を開始する。年間計算として終了時刻を31532400s、計算は間隔3600sにしてみる。年間計算したけれどそこまで計算時間が気にはならなかった。そして年間計算したけれど結局集計や詳細にデータを見るのがたいへんなので部分だけ取り出して計算ができてそうだというのを確認するだけになった。
室温の変化は以下の通りで昼間発熱して温度があがって夜間に換気で外気近くまで温度が下がる様子が計算できた。ただ熱容量や壁の伝熱がないと100Wでこんなに室温があがるものなのかと驚いた。(容積は2.5×5×5m3)
計算開始後の換気量(上)と風速(下)の関係は以下の通りで風速の大きいところでしっかり換気量が増えているのがわかる。風向毎に風圧係数がかわったり浮力(温度差)の影響があったりするので必ずしもこんなにきれいに相関は出ないのが普通かもしれないけど今回はきれいにでた。
csvで出力すると発熱開始と終了のたびにデータが3つでていた。データの集計の際に面倒なことになるので何かよい方法は無いものかなぁと思った。
おわりに
とりあえず時系列の換気計算ができた。理解が間違っている部分があれば指摘していただけるとありがたい。
風圧係数については8月に建築研究所が建築物の自然換気設計のための風圧係数データベースを公開した。まだ読めていないのだけれど、単なるデータベースではなく風圧係数についての知識や考察がたっぷり書いてあるようなのでとても勉強になると思う。このデータベースは32風向分用意されており、日本で得られる気象データは16風向なのでそのまま使える。ただし、今回使った気象データは10°刻みの36風向の気象データになっていたので、このデータベースを使うなら風圧係数を補間してやる必要がでてくる。(線形補間してよいのかは分からないのだけれど、分からなければとりあえず線形補間するのだろう)
次回は自然室温や熱負荷を計算するためのパッケージと思われるBuildings.ThermalZonesについて少し見ていきたいと思う。チュートリアルのSpaceCoolingでは定常計算の壁体熱貫流と換気負荷を見込んだ単純な室だったが、壁体を非定常熱伝導にしたり、窓を取り付けたり、室内の放射伝熱などの計算をしたりなど、より詳細な室の取り扱いができるといいなぁと思う(Buildings.HeatTransferに関連モデルがあるようだけれど室のサンプルはThermalZonesのはず)。次回見るサンプル(Buildings.ThermalZones.Detailed.Validation.BESTEST.Cases6xx.Case600FF)もOpenModelicaではエラーが出るようなのでJModelicaと併用していくと思う。
OpenModelicaでBuildingsライブラリで換気回路網計算を学ぶ_その2
概要
OpenModelicaでLBNLのBuildingsライブラリを使う。初心者なのでいろいろ教えて頂けるとありがたい。
その1ではBuildings.Airflow.Multizoneパッケージを見てExamples.OneRoomにある温度差換気の計算を確認した。風力換気のモデルが見つからなかったので今回は自分で作って使ってみた(実は風力換気用のモデルがあったのでそれも使ってみた)。
使用バージョン
-OpenModelica1.12.0 →Modelica標準ライブラリ3.2.2
-Buildings 5.1.0
作成するモデルの概要
その1で扱ったOneRoomにおいて風が風速2.0[m/s]で吹くものとし、高いほうの窓の風圧係数が-0.2であるとする。低いほうの窓は特に変更しないので風圧係数0.0ということになる。さらに、手計算と比較して検算をしやすくするため、室温と外気温を同じ値にして浮力駆動の換気が起こらないようにする。その他の条件はOneRoomと同じである。
既存モデルの改変
Buildings.Airflow.Multizone.Examples.OneRoomのモデルをベースにするため、モデルを複製する。ファイル→Modelicaクラス新規作成からOneRoomTestというPackageを作り、そこにBuildings.Airflow.Multizone.Examples.OneRoomを複製する。
また、風圧力を考慮したモデルをつくるためにBuildings.Airflow.Multizone.MediumColumnをMediumColumnWithWindという名前で複製しておく。場所はOneRoomTestにする。 このあたりの操作はOpenModelicaでSpaceCoolingを使うときにしたものと同じである。
ファイルを複製したらMediumColumnWithWindに風圧係数と風速を受け取るコネクタを追加し、風圧力を計算する項を追加する。
まず、OMEditのアイコンビューかダイアグラムビューでModelica.Blocks.Interfaces.RealInputをドラッグ&ドロップして名前をvとCpにする。ライブラリブラウザでRealInputで検索をかけてやると見つけやすい。さらにアイコンビュー上でテキストを追加してvとCpとする。既存のテキストを右クリックして複製すると色やサイズなどの設定が楽である。
そして、風圧力を考慮するように以下のように記述する。ここではport_a側(位置が高い方、Top側)に風圧力がかかるようにした。hの最小値は0のままにしているので、このモデルでは高さが低い側に風圧力をかけることはできないことに注意する。
model MediumColumnWithWind "Vertical shaft with no friction and no storage of heat and mass" (略) equation (略) dp = port_a.p - port_b.p;//ここはそのまま // dp = -h*rho*Modelica.Constants.g_n dp = -h*rho*Modelica.Constants.g_n+Cp*0.5*rho*v^2;//ここは書き換え (省略) end MediumColumnWithWind;
このモデルで風圧力を求めるために使っている風圧係数とは風の動圧(速度圧)が建物壁面で静圧に変わる割合のことである。風が吹いているときの壁面の圧力を屋根面平均高さとか軒の高さの動圧で割って算出している。そして風速が大きくなればその動圧に比例して壁面圧力も大きくなるということにしている。風速が変わっても流れ場の性状は風圧係数を求めたときとだいたい同じということを仮定しているのだと思うが、この仮定が有効な風速の条件とかは勉強不足でわからない。レイノルズ数が大きく違ってくるとよくないような気はするがどうなんだろう。
モデルのテスト
風圧力を考慮したモデルができたのでOneRoomで使用するように書き換える。colOutTopのBuildings.Airflow.Multizone.MediumColumnをMediumColumnWithWindに書き換えてやる。ダイヤグラムビューでみると風速と風圧係数をつなぎこむところが使いにくいので右クリックで横反転をしてやる。風圧係数と風速は固定値で与えるのでModelica.Blocks.Sources.Constantをドラッグ&ドロップしてそれぞれCp、とvという名前にする。kにそれぞれ-0.2、2.0を与え、コネクタをつないでやる。
さらに、今は風圧力だけの換気を計算するようにしたいので、浮力が発生しないようにvolOutのInitializationタブのT_startを273.15+20にしてvolEasと同じ値にする。これでモデルを全角文字を含まないパスに保存して、実行する。
手計算だと流量係数0.65、面積0.01m2の開口部を直列合成したときの有効開口面積は0.00459619[m]、密度を1.19684[kg/m3]として圧力差0.478736[Pa]で風量は0.00410554[m3/s]になる。計算結果が0.0041059[m3/s]でだいたい計算はできていそうである。
動圧込みの外気モデル
実はBuildings.Fluid.Sources.Outside_CpとBuildings.Fluid.Sources.Outside_CpLowRiseでは気象データで得られる大気圧に風速と風圧係数から算出した動圧を加えた圧力を使っている。Outside_Cpは風圧係数を定数かコネクタから入力でき、Outside_CpLowRiseはwindPressureLowRiseで風圧係数を計算する。ただし、大気圧と風速の入力はweaBusからなのでReaderTMY3からデータを入力する必要がある。そういうことでこれを使って計算してみることにした。
上の開口部はOutside_CpでCpを-0.2にして下の開口部はOutsideを使うようにした。どちらもredeclare package Medium = Medium
をテキストビューで追加し、接続はnPortsを1にしてport[1]にcolOutTopやcolOutBotにつないだ。
気象データの方はReaderTMY3でpAtmを1.01325[bar]、TDryBulを20[degC]、winSpeを2.0[m/s]としてそれぞれParameterから入力とした。filNamは指定しないと計算できなかったので適当に"C:/OpenModelica1.12.0-64bit/lib/omlibrary/Buildings 5.1.0/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"を指定した。それから接続するときダイアグラムビューで接続するとconnect(weaBus, weaBus)などとなってしまったのでconnect(weaDat.weaBus, out.weaBus)やconnect(weaDat.weaBus, outcp.weaBus) に修正する必要があった。モデルと計算結果は以下のとおり。
風量は0.00406035[m3/s]でだいたい同じ値である。こちらをはじめから使えばよかったのだけれど気づかなかった。サンプルファイルもBuildings.Fluid.Sources.Examples.Outside_Cpにありだいたい同じようなことをやっている。
おわりに
とりあえず風力換気の計算ができた。次はもう少しだけ実践的に気象データを使って時刻変動する換気量を計算したい。
OpenModelicaでSpaceCooingを動かす
概要
OpenModelicaでLBNLのBuildingsライブラリを使う。チュートリアルSpaceCoolingはStstem2、System3がOpenModelicaではエラーが発生して動かなかったのだが、動くように修正する方法をfinbackさんに教えていただいたので紹介する。finbackさんにはお世話になりっぱなしで本当にありがとうございます。
使用バージョン
-OpenModelica1.12.0 →Modelica標準ライブラリ3.2.2
-Buildings 5.0.1
SpaceCoolingと関連モデルの複製とパスの修正
まずは修正したモデル一式を格納するパッケージを作成する。ファイル→Modelicaクラス新規作成を選択しSpaceCoolingTestという名前のPackageを作成する。
SpaceCoolingをパッケージまるごとSpaceCoolingTestパッケージの中に複製する。Buildings.Examples.Tutorial.SpaceCoolingを右クリックして複製を選択。パスをSpaceCoolingTestにしてOKを押す。
さらにBuildings.Fluid.HeatExchangers.WetCoilCounterFlowとBuildings.Fluid.HeatExchangers.DryCoilCounterFlowを同様にして複製する。WetCoilCounterFlowはDryCoilCounterFlowを継承しており、DryCoilCounterFlowがOpenModelicaで問題となっているモデルということになる。複製が終わると以下のようになる。
そしてパスを修正していく。
SpaceCoolingTestの冒頭でimport文によりBuildings.Boundaryconditionsを読み込むようにする。
package SpaceCoolingTest import Buildings.BoundryConditions; package SpaceCooling "Package with example for how to build a model for space cooling" (略)
SpaceCoolingのSystem2とSystem3でそれぞれ複製した方のWetCoilCounterFlowを読み込むようにcooCoiの定義部分でBuildings.Fluid.HeatExchangers.WetCoilCounterFlowとなっている部分のBuildings.Fluid.HeatExchangers.を削除してWetCoilCounterFlowに修正する。コメントアウトした部分が元の記述。
(略) //元はBuildings.Fluid.HeatExchangers.WetCoilCounterFlow cooCoi(略); WetCoilCounterFlow cooCoi(redeclare package Medium1 = MediumW, redeclare package Medium2 = MediumA, m1_flow_nominal = mW_flow_nominal, m2_flow_nominal = mA_flow_nominal, dp1_nominal = 6000, dp2_nominal = 200, UA_nominal = -QCoiC_flow_nominal / Buildings.Fluid.HeatExchangers.BaseClasses.lmtd(T_a1 = THeaRecLvg, T_b1 = TASup_nominal, T_a2 = TWSup_nominal, T_b2 = TWRet_nominal), show_T = true, energyDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial) "Cooling coil" annotation( Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 180, origin = {-30, -26}))); (略)
DryCoilCounterFlowの冒頭にimport文を追加してBuildings.Fluid.HeatExchangers.BaseClassesを読み込む。
model DryCoilCounterFlow "Counterflow coil with discretization along the flow paths and without humidity condensation" extends Buildings.Fluid.Interfaces.PartialFourPortInterface(show_T = false); extends Buildings.Fluid.Interfaces.FourPortFlowResistanceParameters(final computeFlowResistance1 = false, final computeFlowResistance2 = false, from_dp1 = false, from_dp2 = false); import Buildings.Fluid.HeatExchangers.BaseClasses; (略)
モデルの修正
DryCoilCounterFlowにおいて、replaceable BaseClasses.HexElementSensible ele[nEle] constrainedby BaseClasses.PartialHexElement(略)となっている部分を修正する。replaceable文ではクラスを交換することはあってもインスタンスを交換することはあまりないとのこと。また、constrainedbyでクラスを限定するような部分でカッコ内の引数をredeclareするのも一般的ではないのではないかとのこと。MElementというreplaceableなモデルをつくり、これでele[nEle]インスタンスを作成する。コメントアウトした部分が元の記述。
(略) // replaceable BaseClasses.HexElementSensible ele[nEle] constrainedby BaseClasses.PartialHexElement(); replaceable model MElement = BaseClasses.HexElementSensible constrainedby BaseClasses.PartialHexElement; MElement ele[nEle](redeclare each package Medium1 = Medium1, redeclare each package Medium2 = Medium2, each allowFlowReversal1 = allowFlowReversal1, each allowFlowReversal2 = allowFlowReversal2, each tau1 = tau1 / nEle, each m1_flow_nominal = m1_flow_nominal, each tau2 = tau2, each m2_flow_nominal = m2_flow_nominal, each tau_m = tau_m / nEle, each UA_nominal = UA_nominal / nEle, each energyDynamics = energyDynamics, initialize_p1 = {i == 1 and not Medium1.singleState for i in 1:nEle}, initialize_p2 = {i == 1 and not Medium2.singleState for i in 1:nEle}, each deltaM1 = deltaM1, each deltaM2 = deltaM2, each from_dp1 = from_dp1, each from_dp2 = from_dp2, dp1_nominal = {if i == 1 then dp1_nominal else 0 for i in 1:nEle}, dp2_nominal = {if i == nEle then dp2_nominal else 0 for i in 1:nEle}) "Heat exchanger element" annotation( Placement(transformation(extent = {{0, 0}, {20, 20}}))); (略)
WetCoilCounterFlowでele[nEle]はredeclareされているので対応するように修正。こちらもインスタンスを再宣言するのではなくクラス(model)を再宣言するようにする。コメントアウトした部分が元の記述。
(略) //extends Buildings.Fluid.HeatExchangers.DryCoilCounterFlow(redeclare replaceable package Medium2 = Modelica.Media.Interfaces.PartialCondensingGases, redeclare final Buildings.Fluid.HeatExchangers.BaseClasses.HexElementLatent ele[nEle]); extends Buildings.Fluid.HeatExchangers.DryCoilCounterFlow(redeclare replaceable package Medium2 = Modelica.Media.Interfaces.PartialCondensingGases, redeclare final model MElement=Buildings.Fluid.HeatExchangers.BaseClasses.HexElementLatent); (略)
計算実行
修正が終わったファイル一式を保存して実行する。たぶんファイルパスに日本語とか全角文字が含まれていると対応できない。
計算ができなくておかしいと思っていたが、WetCoilCounterFlowを右クリックしての順番をDryCoilCounterFlowの下に変えてやると計算できた。当然といえば当然だが継承元を先に記述しないといけないのだろう。
System2の室温は以下のとおり。
System3の室温は以下のとおり。
おわりに
無事にOpenMoelicaで動作させることができた。多分同じような修正(インスタンスをreplaceable、redeclareしているような部分を書き直す)で他にも現在OpenModelicaで動いていない部分が動くようになったりするのではないかと思う。この修正でDymolaで困ることがなければプルリクやイシューで頼めば直してもらえるはず。
修正方法を教えて頂いたfinbackさんには本当に感謝します。
OpenModelicaでBuildingsライブラリで換気回路網計算を学ぶ_その1
概要
OpenModelicaでLBNLのBuildingsライブラリを使う。初心者なのでいろいろ教えて頂けるとありがたい。
今回はBuildings.Airflow.Multizoneパッケージを見ていく。Buildings.Airflowパッケージでは異なる部屋間や部屋と外部環境との間の空気の流れを計算するためのモデルがあるのだが、直下にはMultizoneパッケージのみがぶら下がっていてそこに各要素のモデルがある。ダクトのネットワークはBuildings.Fluidを見ろと書いてあるのだが多分FixedResistancesとかMoversあたりを使うのだと思う。
このパッケージでできる換気回路網計算はCFDとは異なり、空間をそれぞれ1つの点で表現し、空間同士を開口による流れの抵抗のネットワークとしてつないでいくものだ。年間の自然換気量の変化の影響を見たいときなどCFDで非定常計算をするのはあまり実用的ではないのでこちらを使ったりする。定常計算でもこちらの方がざっくり設定できるし1ケースの計算時間もたぶん早いので都合がよいことも多い。
使用バージョン
-OpenModelica1.12.0 →Modelica標準ライブラリ3.2.2
-Buildings 5.1.0
Buildings.Airflow.Multizoneの構成
名称 | 説明 |
---|---|
UsersGuide | ユーザーガイド |
DoorDiscretizedOpen | 高さに沿って離散化したドアモデル |
DoorDiscretizedOperable | 高さに沿って離散化したドアモデル |
EffectiveAirLeakageArea | 有効漏気面のモデル |
MediumColumn | 摩擦がなく熱と質量の蓄積がない垂直軸のモデル |
MediumColumnDynamic | 摩擦はないが熱と質量の蓄積がある垂直軸のモデル |
Orifice | オリフィス(単純開口)のモデル |
ZonalFlow_ACS | 1秒あたりの換気量の入力によるゾーン流のモデル |
ZonalFlow_m_flow | 1秒あたりの換気量の入力によるゾーン流のモデル |
Types | 型の定義のパッケージ |
Examples | モデルの使用法やテストモデルなどのパッケージ |
Validation | バリデーション用のモデルのパッケージ |
BaseClasses | Buildings.Airflow.Multizoneの基底クラスのパッケージ |
ユーザーガイドと型定義やサンプルや検証や基底クラスなどのパッケージがあるが実際に使用するモデルは8個である。正直ユーザーガイドには大したことは書いていないのでExamplesを見ながらなんとなく組み上げていくのだと思う。
Typesパッケージで定義されているものは1つだけでdensitySelectionというMediumColumnモデルの密度の設定パラメータとなる列挙型の変数があるのみである。
type densitySelection = enumeration( fromTop "Density from top port", fromBottom "Density from bottom port", actual "Actual density based on flow direction") "Enumeration to select density in medium column";
Examplesパッケージは結構たくさん例がある。
名称 | 説明 |
---|---|
CO2TransportStep | 浮力駆動によるCO2輸送モデル |
ChimneyShaftNoVolume | シャフトの定常状態モデルでの煙突効果を示すモデル |
himneyShaftWithVolume | シャフトの動的モデルによる煙突効果を示すモデル |
ClosedDoors | 3つの閉じたドアのモデル |
NaturalVentilation | 密度差による流れの逆転のテストモデル |
OneEffectiveAirLeakageArea | 有効漏気面を持つモデル |
OneOpenDoor | 1つの開いたドアと1つの閉じたドアのモデル |
OneRoom | マルチゾーン空気交換モデルの検証のための1つの室のモデル |
Orifice | オリフィスのモデル |
ReverseBuoyancy | 4つの室と逆流する浮力駆動型空気循環モデル |
ReverseBuoyancy3Zones | 3つの室と逆流する浮力駆動の空気循環モデル |
ZonalFlow | 2つの室で所定の空気交換を行うモデル |
ValidationパッケージはThreeRoomsContamモデル一つだけである。Michael WetterのMultizone Airflow Model in Modelicaに詳細な内容が書いてあるようだ。
Buildings.Airflow.Multizone.Examples.OneRoom
とりあえずサンプルとして一室モデルを見ていく。
室volEasと外気volOutを、上下の開口部oriOutTopとoriOutBotでつないで温度差換気を行っているモデルである。室と開口部の間はcolEasInTop、colEasInBot、colOutTop、colOutBotという高さ方向の距離を示すモデルでつないでいる。
connect(colEasInTop.port_a, oriOutTop.port_a); connect(colEasInTop.port_b, volEas.ports[1]); connect(colEasInBot.port_a, volEas.ports[2]); connect(colEasInBot.port_b, oriOutBot.port_a); connect(oriOutBot.port_b, colOutBot.port_b); connect(colOutBot.port_a, volOut.ports[1]); connect(colOutTop.port_b, volOut.ports[2]); connect(colOutTop.port_a, oriOutTop.port_b);
空気の流れの計算なので媒体としてBuildings.Media.Airを使用している。
package Medium = Buildings.Media.Air;
空間のモデルの設定
室volEasの設定はSpaceCoolingで見たときと比べて、熱容量の係数を使っていない(家具などの熱容量を考慮しない)、massDynamics=Modelica.Fluid.Types.Dynamics.SteadyStateInitialを指定する、m_flow_nominal=0.001が0に近い小さな値になっているなどの違いがある。
以下に設定を示す。
Buildings.Fluid.MixingVolumes.MixingVolume volEas( redeclare package Medium = Medium, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, T_start=273.15+20, V=2.5*5*5, nPorts=2, m_flow_nominal=0.001, massDynamics=Modelica.Fluid.Types.Dynamics.SteadyStateInitial);
外気volOutはモデルとしては室と同じものを使用している。
体積を非常に大きくとっているのは室との換気で温度が変動しないようにするためだろうか。また、外気側では圧力を指定している。外気を圧力の基準とするような意味合いだと思うがMedium.p_defaultで大気圧を与えている。こちらのmassDynamicsはFixedInitialになっている。これで圧力固定になるのだろうか。
Buildings.Fluid.MixingVolumes.MixingVolume volOut( redeclare package Medium = Medium, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, T_start=273.15 + 10, V=1E12, p_start=Medium.p_default, nPorts=2, m_flow_nominal=0.001, massDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial);
開口部のモデルの設定
上下の開口部oriOutTopとoriOutBotをまとめて示す。
Buildings.Airflow.Multizone.Orifice oriOutTop( redeclare package Medium = Medium, A=0.01, m=0.5); Buildings.Airflow.Multizone.Orifice oriOutBot( redeclare package Medium = Medium, A=0.01, m=0.5);
OMEdit上の設定画面は以下のとおり。
オリフィスの流量係数は0.65がデフォルトになっており今回はデフォルト値をつかっている。ForceErrorControlOnFlowAはよくわからないが流量を見たいときはtrueにしておくらしい。Aが開口面積、mは0.5が乱流時で1が層流時を示すらしい。useDefaultPropertiesはfalseにすると実際の密度と粘性係数を使用し、trueだとデフォルト値を使用するようになっている。dp_turbulentは層流と乱流が一致するときの差圧?だが0.1を推奨しているらしい。lWetはレイノルズ数の計算に使用するパラメーターなので水力直径だろう。密度の扱いは計算の安定性に関わるので設定があるのはわかるけれど、粘性係数は気にしたことがなかった。乱流層流の切替も気にしたことがなかったけど確かに流量が変わりそうな気はする。
以下の残りの2つのタブは流れに関係する設定でよくあるやつだった。
高さ方向の距離を示すモデルの設定
Buildings.Airflow.Multizone.MediumColumnは開口部の高さ位置を指定するためのモデルなのだと思う。浮力換気のための高低差による圧力の変動を計算しているのだと思う。設定を以下に示す。
Buildings.Airflow.Multizone.MediumColumn colOutTop( redeclare package Medium = Medium, h=1.5, densitySelection=Buildings.Airflow.Multizone.Types.densitySelection.fromBottom); Buildings.Airflow.Multizone.MediumColumn colOutBot( redeclare package Medium = Medium, h=1.5, densitySelection=Buildings.Airflow.Multizone.Types.densitySelection.fromTop); Buildings.Airflow.Multizone.MediumColumn colEasInTop( redeclare package Medium = Medium, h=1.5, densitySelection=Buildings.Airflow.Multizone.Types.densitySelection.fromBottom); Buildings.Airflow.Multizone.MediumColumn colEasInBot( redeclare package Medium = Medium, h=1.5, densitySelection=Buildings.Airflow.Multizone.Types.densitySelection.fromTop);
OMEdit上の設定画面は以下のとおり。
hが高さ方向の距離を示し、Topにつないだほうが上、Bottomにつないだほうが下という位置関係になるようだ。ここでの室の圧力の基準位置がどこだかわからないが、基準位置を床にして上に0.5と3.5などのように床面と開口面高さ方向中央位置で指定したほうがよさそうな気がする。このあたりは自分で整合性をとっておけばたぶん問題はないとは思う。
densitySelectionではモデルのどちら側の密度を使用するかを指定している。TopとBottomの間にはρghだけ圧力差があるのだが、このときのρをどちら側からとってくるかを選んでいるのだろう。actualという選択肢もあるのでそのときは風上側の密度を使用するのだと思う。
計算実行
温度差換気(浮力駆動の換気)で気にすることはだいたい以下のとおり。
* 外気はどの高さでも同じ温度、室内もどの高さでも同じ温度(完全混合の仮定)
* 温度(=室)によって密度ρが変わる。
* 高さにより「密度ρ × 重力加速度g × 高さh」だけ圧力が変わる。
* 温度(=密度)が異なる二つの空間の間の圧力差は高さによって変わる。
* 圧力差によって流れが発生。「開口面の高さでの圧力差により流れを計算」するので同じ室の間でも開口部ごとに流れの方向がかわることができる。
計算結果は以下の通り。とりあえず1秒だけ計算している。
自分で計算をしてみると0.0065[m3/s]だったのでだいたいよさそうである。
1時間分計算してみると室温が下がっている様子がわかる。
圧力は以下のとおり。外気の圧力が一定なのが確認できた。室の圧力が外気を上回ったり下回ったり変動しているように見えるがレンジの設定が細か過ぎるだけでほぼ外気と同じ圧力となっている。ちなみにcsvでデータ出力すると1.01325[bar]で一定値となってでてくる。桁落ちされるのは困るのでどうにかしたいが大気圧との差分をどこかで計算すれば場当たり的には対処できそうな気はする。しかしなんでグラフ上で見える値をそのまま書き出せないのだろう。ちなみに単位が[bar]なのは[Pa]に直すのを忘れていただけでグラフ上もcsvも[Pa]にできる。
おわりに
なんとなく雰囲気は分かったような気がするけれど、まだあまり仕組みはよく分かっていない。Fluidportをつないであげれば開口部では圧力から流量と計算し、室のほうで流量の収支をとるように圧力を補正してくれているのだろうか。開口への風圧の与え方もわからないのだけれど、別のFluidポートをつなぎこんで圧力だけあたえるとかはできなさそうな気がするのでMediumColumnに手を加えて風圧力を組み込むしかないのかもしれない。あと一応ちゃんと論文を読んだほうがよさそうである。
OpenModelica(とJModelica)でBuildingsライブラリを学ぶ_その9
概要
OpenModelicaでLBNLのBuildingsライブラリを使う。初心者なのでいろいろ教えて頂けるとありがたい。
前回SpaceCoolingのSystem2をやったので今回はSystem3をやる。
使用バージョン
-OpenModelica1.12.0 →Modelica標準ライブラリ3.2.2
-JModelica2.2 →Modelica標準ライブラリ3.2
-Buildings 5.0.1
System3の概要とSystem2からの変更点
System2では気象データファイル読み取り用のモデルweaDatを使用していたものの、使用時は定数を設定して一定の外気温を出力しているだけだった。今回はその部分をちゃんと気象データファイルを読み込んで外気温を出力するように変更する。また、一定の外気温度の場合は定常状態となりオープンループ制御でも一定の室温に収束していたが、外気温が変動するとそうもいかなくなるので閉ループ制御を追加する。
それからvolのenergyDynamicsがFixedInitialからSteadyStateInitialにかわっていた。このタイミングで変更した理由はよくわからない。
閉ループ制御のために新しく追加したモデルはオンオフコントローラーcon、設定温度TRooSetPoi、室温センサーsenTemRooであり、ポンプ流量mWat_flowはSystem2とは別のモデルを使用している。これらはModelica標準ライブラリを使って実装している。Modelica標準ライブラリでuがインプット、yがアウトプットになっているのは何かの略なのだろうけど何なんだろう。追加したモデルのコネクタの設定を以下に示す。
connect(TRooSetPoi.y, con.reference); connect(vol.heatPort, senTemRoo.port); connect(senTemRoo.T, con.u); connect(con.y, mWat_flow.u); connect(mWat_flow.y, souWat.m_flow_in);
senTemRooはvolから温度をもらってconに渡している。conは別のポートにもTRooSetPoiから温度をもらっている。conからオンオフの制御信号をmWat_flowに送り、mWat_flowが信号を流量にしてsouWatに渡している。
気象データ読取モデルweaDat
前回はこのモデルをつかいながらも外気温は定数を出力していたが今回は.mosファイルからデータを読み取って出力する。そのため、TDryBulSouをBuildings.BoundaryConditions.Types.DataSource.ParameterからBuildings.BoundaryConditions.Types.DataSource.Fileへ変更している。TDryBul=TOut_nominalが残っているのは初期値として使うからだろうか。設定しなくてもよいかもしれない。
BoundaryConditions.WeatherData.ReaderTMY3 weaDat( pAtmSou=Buildings.BoundaryConditions.Types.DataSource.Parameter, TDryBul=TOut_nominal, filNam=Modelica.Utilities.Files.loadResource("modelica://Buildings/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"), TDryBulSou=Buildings.BoundaryConditions.Types.DataSource.File)
オンオフコントローラーcon
ややこしいが熱コンダクタンス用のモデルのインスタンスはtheConという名前でこれとは別物である。 TRooSetPoiから設定温度をreferenceに、senTemRooから計測温度をuに受け取り、mWat_flowへyを受け渡している。帯域幅は1[K]に設定している。
Modelica.Blocks.Logical.OnOffController con(bandwidth=1) "Controller for coil water flow rate";
Modelica.Blocks.Logical.OnOffControllerの実装は以下の通り。
block OnOffController Blocks.Interfaces.RealInput reference Blocks.Interfaces.RealInput u Blocks.Interfaces.BooleanOutput y parameter Real bandwidth(start=0.1) parameter Boolean pre_y_start=false initial equation pre(y) = pre_y_start; equation y = pre(y) and (u < reference + bandwidth/2) or (u < reference - bandwidth/2); end OnOffController;
pre(y)で1時刻前のyの値を参照している。yが論理演算になっているが設定温度-0.5×帯域幅より低い場合はtrue、設定温度+0.5×帯域幅より高い場合がfalseであることに注意。bandwidthの範囲の温度のときはpre(y)と同じになる。
設定温度TRooSetPoi
TRooSetPoiは定数を出力するだけのモデルである。conが設定値をコネクタからもらってくる仕様になっているため追加されている。
Modelica.Blocks.Sources.Constant TRooSetPoi(k=TRooSet)
室温センサーsenTemRoo
volから温度をもらってconへ出力している。特に設定はない。
Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor senTemRoo
conの入力がReal型の数値であり、volからのコネクタがHeatPortかFluidportなので、HeatPortから温度をもらってReal型の数値として出力している。 Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensorの実装は以下の通り。
model TemperatureSensor Modelica.Blocks.Interfaces.RealOutput T(unit="K"); Interfaces.HeatPort_a port; equation T = port.T; port.Q_flow = 0; end TemperatureSensor;
ポンプ流量mWat_flow
mWat_flowのモデルをModelica.Blocks.Sources.ConstantからModelica.Blocks.Math.BooleanToRealに置き換える。ポンプsouWatの入力はBoolean型のオンオフ信号を使えないのでオンオフ信号を流量に変換するために使っている。OnOffControllerは暖房向けのオンオフになっており、冷却時の設定としてtrueで0、falseでmW_flow_nominalを出力している。
Modelica.Blocks.Math.BooleanToReal mWat_flow(realTrue=0, realFalse= mW_flow_nominal)
Modelica.Blocks.Math.BooleanToRealの実装は以下の通り。
block BooleanToReal "Convert Boolean to Real signal" parameter Real realTrue=1.0; parameter Real realFalse=0.0"; Blocks.Interfaces.RealOutput y; equation y = if u then realTrue else realFalse; end BooleanToReal;
計算実行
やっぱりOpenModelicaでは実行できないので前回と同じくJModelicaで実行してみる。
計算は15552000[s]から15638400[s]まで9732個のデータが出力されており一日分の計算になっているものの時間間隔が均等ではなかった。そういうものなのだろうか。
* 室温と外気温
外気温が変動しているが、室温はオンオフ制御でだいたい設定温度±0.5[K]くらいになっている。グラフの形もまぁチュートリアルのドキュメントにあるものと同じ形状にはなっている。ちなみにweaDatのTDryBulSouは常に1を、TDryBulは常に305.5を出力しており、実際に外気温を確認できるのはTDryBul_in_internalである。TDryBulはあくまで一定値の出力用、TDryBulSouは設定値Buildings.BoundaryConditions.Types.DataSource.Fileを示す数値が出力されているだけのようだった。
ポンプの水の発停
ポンプの流量も一応確認。コイル水側の出入口温度
水の出入口温度はポンプが停止して流量がなくなってもコイルを通過する空気温度になっているようである。流量が0だから計算できないとかにはなっていないらしい。
おわりに
コネクタの型をあわせるためにモデルを追加するのはもう少しシンプルにできないものかなぁと思ったけどモデルを入れ子にしてもう少しまとまりをつくるとすっきりするのだろうか。今回追加した4つのモデルをまとめて一つのモデルとして扱ってもいいような気がする。とりあえずBuildingsライブラリのExamples/Tutorial/SpaceCoolingはひとまずこれで終わり。このチュートリアルの中でもいろいろ疑問を放置したままになっていることが多いのでそのあたりは少しずつ整理してつぶしていきたいと思った。ライブラリの.moファイルのannotationにそれぞれ書いてあるドキュメントの日本語訳作業ものんびりはじめた。
さすがに全部を訳し切るのはできない気がするけれど使用するモデルの整理のついでくらいに思って部分的にでもやろうと思う。なによりもう一個の方がまだ終わってないので図とかそろえてさっさと形を整えてあげないといけないのだけれど。。。
とりあえずブログでは次回からはAirflowのExampleでも見ながら建物の換気回路網計算をしたいと思う。
OpenModelica(とJModelica)でBuildingsライブラリを学ぶ_その8
概要
OpenModelicaでLBNLのBuildingsライブラリを使う。初心者なのでいろいろ教えて頂けるとありがたい。
SpaceCoolingのSystem2をやる。前回でモデルの設定は全部見たので今回は計算をまわしたい。
使用バージョン
-OpenModelica1.12.0
-JModelica2.2 → Modelica標準ライブラリ3.2?
-Buildings 5.0.1
JModelicaを使う
System2の計算を実行しようとOpenModelicaで実行したところコンパイルエラーが発生した。
もともとBuildingsライブラリの動作検証はDymolaという商用ソフトとJModelicaというOSSソフトでしか行っていないのだった。そういうわけでJModelicaを使うことにした。Windows環境でのインストールは公式サイトからバイナリインストーラをダウンロードしてきて実行すればたぶん悩むことは無いと思う。
JModelicaはOMEditのようなGUIでモデルを設定するツールがないようだ。OMEditでモデルを作成して実行はJModelicaというのもありかもしれないし、ちょっとしたものならVSCode(Modelica用の拡張機能がある)などテキストエディタで書くのもよいかもしれない。
次に書くJModelicaの使い方はfinbackさんに教えて頂きました。ありがとうございます。
- Buildingsライブライリを適当な作業場所へ置いてBuildingsライブライリのフォルダの名前をバージョン名抜きのBuildingsという名称にする。
- JModelicaのIPythonを実行し、cdでBuildingsフォルダを置いた場所へ移動する。
- 以下のコードを入力してSystem2のモデルをfmuファイルにコンパイルする。
from pymodelica import compile_fmu fmufile = compile_fmu('Buildings.Examples.Tutorial.SpaceCooling.System2','Buildings')
* これダメじゃないかと思うようなすごい勢いで「ファイルが見つかりません」を訴えかけてきてエラーを出しながらもBuildings_Examples_Tutorial_SpaceCooling_System2.fmuファイルが生成される。気にせず以下のコードを入力して生成されたfmuファイルを実行する。
from pyfmi import load_fmu model = load_fmu('Buildings_Examples_Tutorial_SpaceCooling_System2.fmu') model.simulate()
- Buildings_Examples_Tutorial_SpaceCooling_System2_result.mat が出力されるのでJModelicaのplot-GUIで読み込む。
このmatファイルをOMEditで読み込むと温度は絶対温度でのみ見ることができる。System1ではOpenModelicaで実行して結果を読み込むと温度を摂氏と絶対温度と切り替え表示ができていたのでJModelicaで実行したときの仕様だと考えられる。
System2のおさらい
System2の簡単なおさらいは以下の通り。
* 熱容量を持った室に発熱1000Wと熱貫流を熱流としてコネクタから与えている。
* さらに流体を与えるコネクタから冷気を給気して冷やしている。
* 室の熱貫流はテキストデータから読み取った外気温度から計算。
* 室にコイルで冷却した外気を給気。この外気温度もおなじテキストデータから読み取っている。
* 外気はファンの位置で質量流量固定。
* 室の排気は冷却コイルに入る前の外気と顕熱交換。
* コイルの冷水側は温度固定、流量固定
パラメータと各モデルの設定を以下の表に示す。
変数名 | 説明 | 値 |
---|---|---|
V | 室容積[m3] | 6*10*3 |
eps | 熱交換器の熱交換効率[-] | 0.8 |
TASup_nominal | 室の給気温度の公称値[K] | 273.15+18 |
TRooSet | 室の設定室温[K] | 273.15+24 |
TOut_nominal | 外気の設計温度[K] | 273.15+30 |
THeaRecLvg | 給気側の熱交換器出口温度[K] =給気側のコイル入口温度[K] |
TOut_nominal -eps*(TOut_nominal-TRooSet) |
QRooInt_flow | 室の発熱[W] | 1000 |
QRooC_flow_nominal | 室の冷却負荷の公称値[W] | -QRooInt_flow -10E3/30*(TOut_nominal-TRooSet) |
mA_flow_nominal | 空気の質量流量の公称値[kg/s] 温度変化後を考慮して1.3倍? |
1.3*QRooC_flow_nominal/1006 /(TASup_nominal-TRooSet) |
dTFan | ファンによる想定温度上昇[K] | 2 |
QCoiC_flow_nominal | 熱交換器と潜熱負荷を考慮にいれたコイルの冷却負荷[W] | 4*(QRooC_flow_nominal +mA_flow_nominal*(TASup_nominal -THeaRecLvg-dTFan)*1006) |
TWSup_nominal | 水の往き温度?[K] | 273.15+16 |
TWRet_nominal | 水の還り温度?[K] | 273.15+12 |
mW_flow_nominal | 水の質量流量の公称値[kg/s] | QCoiC_flow_nominal/(TWRet_nominal-TWSup_nominal)/4200 |
インスタンス名 | 用途 | 設定 |
---|---|---|
vol | 室 | redeclare package Medium = MediumA m_flow_nominal=mA_flow_nominal V=V nPorts=2 energyDynamics= Modelica.Fluid.Types.Dynamics.FixedInitial mSenFac=3 |
theCon | 室の壁体の熱コンダクタンス | G=10000/30 |
TOut | 外気温 | なし |
preHea | 室の発熱ソース | Q_flow=QRooInt_flow |
fan | 給気ファン | redeclare package Medium=MediumA m_flow_nominal=mA_flow_nominal energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) |
hex | 熱交換器 | redeclare package Medium1=MediumA redeclare package Medium2=MediumA m1_flow_nominal=mA_flow_nominal m2_flow_nominal=mA_flow_nominal dp1_nominal=200 dp2_nominal=200 eps=eps |
cooCoi | 冷却コイル | redeclare package Medium1= MediumW redeclare package Medium2=MediumA m1_flow_nominal=mW_flow_nominal m2_flow_nominal=mA_flow_nominal dp1_nominal=6000 dp2_nominal=200 UA_nominal=-QCoiC_flow_nominal /Buildings.Fluid.HeatExchangers.BaseClasses.lmtd( T_a1=THeaRecLvg,T_b1=TASup_nominal ,T_a2=TWSup_nominal,T_b2=TWRet_nominal) show_T=true energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial |
out | 外気 | nPorts=2 redeclare package Medium=MediumA |
souWat | 冷水ポンプ (流量ソース) |
nPorts=1 redeclare package Medium=MediumW use_m_flow_in=true T=TWSup_nominal |
sinWat | 冷水の排出先 | nPorts=1 redeclare package Medium=MediumW |
weaDat | 気象データ | pAtmSou=Buildings.BoundaryConditions.Types.DataSource.Parameter TDryBulSou=Buildings.BoundaryConditions.Types.DataSource.Parameter TDryBul=TOut_nominal filNam= Modelica.Utilities.Files.loadResource( "modelica://Buildings/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos") |
weaBus | 気象データ用バス | なし |
mAir_flow | 給気風量 | k=mA_flow_nominal |
mWat_flow | 冷水流量 | k=mW_flow_nominal |
senTemHXOut | 給気側熱交換器出口温度 | redeclare package Medium=MediumA m_flow_nominal=mA_flow_nominal |
senTemSupAir | 給気側コイル出口温度 | redeclare package Medium=MediumA m_flow_nominal=mA_flow_nominal |
TWSup_nominalとTWRet_nominalはおそらく名前が逆である。
パラメータは直接数値を指定したものと数式で入力したデータがある。だいたい次のような流れでパラメータを数式で指定している。考え方を残しておくという意味で良いと思うし、パラメータは計算の途中で変更できない仕様なのでたぶんモデルを呼び出すたびに計算して遅くなるとかもないはず。
* 設定室温から室の負荷を求める。
* 室の負荷と給気温度から空気の風量を求める。
* 空気の風量とコイルの空気側の入口出口温度差からコイルの処理負荷を求める。
* コイルの処理負荷と水の入口出口温度差から水の流量を求める。
ここで空気の風量を1.3倍している理由がちょっとわかっていない。
System2の実行
ここで注目すべきは開ループ制御により室温vol.Tが設計温度273.15+24=297.15[K]になっているかである。ついでに熱交換器からの排気の影響が気になっていたので給気側外気条件の温度out.Tが273.15+30=303.15[K]になっているかを見る。
外気のほうは排気の影響はなさそうだが、室温が少し低くなっている。風量1.3倍がよくないのではないかと思ったが公式のドキュメントでも室温が低くなっていて計算結果自体はだいたいあっていそうではある。念のために風量を1.3倍→1.0倍として計算してみた。CoocoiでShou_TをTrueにしていたのでそこの温度も表示してみる。Fluidportからは標準では温度がでないためこの設定により温度出力用のportができていた。
JModelicaの結果表示からテキストデータでの書き出しがよく分からないのでOMEditのほうでCSVデータを書き出して計算終了時点の温度を見てみる。
名称 | 変数名 | 設計温度 | 計算温度 |
---|---|---|---|
室温 | vol.T | 24℃ | 23.758℃ |
空気側コイル出口温度 | a1.T | 16℃ | 18℃ |
空気側コイル入口温度 | a2.T | 25.2℃ | 25.038℃ |
水側コイル出口温度 | b1.T | 16℃ | 17.818℃ |
水側コイル入口温度 | b2.T | 12℃ | 16.648℃ |
風量を直すと室温はそれらしい値になった。ただ給気温度となるコイル出口温度が低いしコイルの水側にいたっては固定値のはずのコイル入口温度が全然違う。System2で想定される計算結果といえるのが風量1.3倍にしていたもののグラフしかなくて、それはまぁだいたいそれっぽくなってはいたけれど、どうにも不安になる結果である。まぁ細かい検証とかはまた別の機会にやりたいと思う。
おわりに
今回は結果を見るときにそんな変数あったっけっていうものまで並んでいたので表示したい変数を探すのが少し手間でした。なにかよい方法はないかなぁと。それから、慣れもあると思うけれどプレとかポストの処理はOpenModelicaがやっぱりやりやすくて、Buildingsライブラリを使うにしてもJModelicaと併用か、OpenModelicaで計算できるようにしたいなぁと思いました。JModelicaの計算もこれで大丈夫なのか不安なところもあるし、新たな課題が見つかったような感じです。
OpenModelicaで計算できなかったときはとても困ったけれどfinbackさんの助けによりなんとか計算ができました。本当に感謝しています。まだまだ知らない事だらけだけれどSystem2を通してまた少し理解が進みました。次はSystem3をやります。
OpenModelicaのBuildingsライブラリを学ぶ_その7
概要
OpenModelicaでLBNLのBuildingsライブラリを使う。初心者なのでいろいろ教えて頂けるとありがたい。
SpaceCoolingのSystem2をやる。前回はhexとoutとsenTemHXOut廻りを見たので今回はcooCoiとsouWat廻りを見る。計算までやりたかったけれどそれは次回いろいろいじりながらやってみたい。のんびりやりすぎな気がしなくもないが続けることが大事なのだと思う。
使用バージョン
-OpenModelica1.12.0 →Modelica標準ライブラリ3.2.2
-Buildings 5.0.1
チュートリアル SpaceCoolingのSystem2
今回は水配管廻りを見ていく。mWatで指定された流量の冷水を冷水ポンプsouWatで冷却コイルcooCoiに送り、還りの冷水はsinWatにつながっているというものである。
cooCoi以外の3つのモデルの使い分けは以下のようになっている。FixedBoundaryとMassFlowSource_Tの違いがやや分かりにくいような気がするので後で確認したい。
* Modelica.Blocks.Sources.Constant→定数を出力
* Buildings.Fluid.Sources.FixedBoundary→流体(Medium)の状態を出力
* Buildings.Fluid.Sources.MassFlowSource_T→流量と温度の設定をして流体(Medium)の状態を出力
cooCoiとsouWat廻りのコネクタは以下のとおり。
connect(souWat.ports[1], cooCoi.port_a1); connect(cooCoi.port_b1, sinWat.ports[1]); connect(mWat_flow.y, souWat.m_flow_in); connect(senTemHXOut.port_b, cooCoi.port_a2); connect(cooCoi.port_b2, senTemSupAir.port_a);
コイルはport_a1とport_b1が水、port_a2とport_b2が空気のコネクタになっている。
mWat廻り
mWatの設定は以下のとおり。
Modelica.Blocks.Sources.Constant mWat_flow(k=mW_flow_nominal)
mAir_flowとおなじでBuildingsライブラリではなくModelica標準ライブラリを使って流量を定数で出力している。
sinWat廻り
sinWatの設定は以下のとおり。
Buildings.Fluid.Sources.FixedBoundary sinWat(nPorts=1, redeclare package Medium = MediumW)
出力用のコネクタの数の設定と流体の指定をしている。冷水の設定なので変数としてMediumW(=Buildings.Media.Water)を指定している。特に数値を設定しているわけでもないので、冷却コイルの出口がどこかへ値を渡す必要がありとりあえずつくっているものなのかもしれない。たぶんFixedBoundaryというよりGradientZeroみたいな条件になっているような気がする。
OMEdit上の設定は以下のとおり。
設定できるのは、圧力と密度、温度と比エンタルピ、湿度?、その他汚染物質等、が設定できるようである。どうやら境界条件用のモデルなので相手からこのモデルに流れてくる流れ方向のときは圧力を除いて影響がないらしい。流出境界になるときは圧力境界条件としては使えるけれど、出口温度固定などをしたいならこのモデルではダメなんだと思われる。
souWat廻り
souWatの設定は以下のとおり。
Buildings.Fluid.Sources.MassFlowSource_T souWat( nPorts=1, redeclare package Medium = MediumW, use_m_flow_in=true, T=TWSup_nominal)
出力用のコネクタの数、流体、流量コネクタ使用の有無、出力する温度を指定している。use_m_flow_in=trueとすることでmWatから流量を受け取ることができる。nominalとついてある値を入力するときはだいたい計算を行うときのオーダーがどの程度なのかを数値計算上の理由により指定しているもののような気がしていたのだが、ここでは出力する温度を指定している。まぁモデル側ではただのTなので深く考えるところではないかもしれない。
OMEdit上の設定は以下のとおり。
FixedBoundaryとの違いはいくつかあるのだけれど、まず圧力と密度ではなく流量を扱っている点とこちらは比エンタルピが使えない点がある。それから、FixedBoundaryはその名前のとおり定数を指定しなければならなかったけれど、MassFlowSource_Tはinputのコネクタから値を受け取って出力することができ、コネクタのオンオフの設定がある。流出境界の扱いについてはこちらは流量のみ有効になるようだ。
本来ポンプとしてもモデルはファンで使ったものと同じものを使うのだけれど、これでも流量を指定できるのでポンプのように使うこともできるということだろう。
cooCoi廻り
cooCoiの設定は以下のとおり。
Buildings.Fluid.HeatExchangers.WetCoilCounterFlow cooCoi(redeclare package Medium1 = MediumW, redeclare package Medium2 = MediumA, m1_flow_nominal=mW_flow_nominal, m2_flow_nominal=mA_flow_nominal, dp1_nominal=6000, dp2_nominal=200, UA_nominal=-QCoiC_flow_nominal/ Buildings.Fluid.HeatExchangers.BaseClasses.lmtd( T_a1=THeaRecLvg, T_b1=TASup_nominal, T_a2=TWSup_nominal, T_b2=TWRet_nominal), show_T=true, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
コイルはモデル名から向流型熱交換器で潜熱負荷も処理するモデルだろうと思われる。2つの流体、流量、差圧、熱コンダクタンスと温度表示、計算モデルの種類の設定を行っている。熱コンダクタンスはコイルの処理熱量を対数平均温度差で割って逆算してもとめているので熱コンダクタンス×対数平均温度差で処理熱量を求めるモデルであることが想定される。
OMEdit上の設定は以下のとおり。コイルも熱交換器の一種なので空気の熱交換器で見たものと同じパラメータが多い。
↑2つの流体、流量、差圧、熱コンダクタンスの指定に加えて、空気と水の対流熱伝達率の比、空気と水とコイルそれぞれの時定数を指定できる。あとnEleはコイルの離散化時の分割数らしく、コイルをいくつかの部分に区切って計算しているらしい。コイルは解析的に長さで積分して出口温度出すやつじゃないのだろうか。コイルのパラメータを指定してコイルの熱コンダクタンスを求めたりはできないらしい。
↑流れの逆流に関する指定。熱交換器で見たのと同じ。
↑流量0近傍の扱い。熱交換器で見たのと同じだがホモトピー法は使っていないようだ。
↑流れの抵抗に関する指定。熱交換器で見たのと同じ。
↑エネルギーバランスの式の設定。ファンとか室で見たのと同じもの。
↑水と空気それぞれの対流熱伝達率が流量や温度に依存するかどうかの設定。デフォルトでは流量のみに依存となっている。ラジエーターみたいなものだと空気側は温度に依存とかするのかもしれない。
↑拡散に近似する熱コンダクタンス?の設定。とりあえず流量0近傍の扱いなので計算安定化に寄与するのかもしれないがExperimentalの項目なので気にしなくてもいいだろう。
おわりに
ようやくSystem2のモデルの設定を全部確認できた。次回は計算して気になってたところとかの確認をしたい。このライブラリのドキュメントはあまり読み込まず適当にやっていたけれど、もうちょっとちゃんとしないとなぁと思ってきたので翻訳をはじめてみた。HPのほうのユーザーガイド。どうでもいいところから訳し始めている感が強いが短いところからやっていきたい性分なのだと思う。
github.com
英語は得意でもないし、意味はなんとなくわかっても日本語にするのが難しかったりして翻訳なんて無駄な作業なんじゃないかと思うのだけれど、git使ってみたかったというのもあるしよいのだ。まだ途中だけれど終わったらライブラリ内のドキュメントを訳していこうかと思う。ただドキュメントに知りたいこと全部書いてるわけでもないんだよなぁ。。。