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さんには本当に感謝します。