扩展包和访问内容
Extending packages and access to the content
我继续努力了解如何最好地划分库和应用程序中的代码。在之前的几篇文章中,我使用了带有应用程序 dxx_app7 的玩具示例 DEMO_xx 库。下面是一个稍微更新的版本来解决这里的问题。我已经包括了在收获箱中添加传感器的可能性。
现在我想了解如何在应用程序代码中引入从库 Medium2 扩展而来的应用程序 Medium7 的信息,并在应用程序的新组件模型中充分使用这些信息。
我的理解是,如果你导入一个从另一个包扩展的包,你只会得到什么是“最新”包,而不是通过扩展构建的包以及聚合的总 Medium7 信息。
示例中通过将常量 SensorX.component 从有效的 C 更改为无效的 A 或 B 来说明这一事实。
但是,如果我创建一个 Medium7 的本地实例,那么我将获得 Medium7 的完整信息。我可以在 SensorX 中按照标记为问题 1 - 替代 2 的方式执行此操作。
我也可以在系统配置中选择基板来测量并标记问题 1 alt 3。我认为这是更具可读性的代码。
但是我如何让 Medium7 的所有内容在本地可用?我是否必须像我在此处使用 sensorX.component 显示的那样,为我需要的每个常量在本地定义一个新常量?通常,您可能希望在模型中访问介质的各种属性,并且方便放入包 Medium
我也希望我可以导入一个适用于 Medium7 的连接器 LiquidCon,而不是在 Sensor7 包中再次编写该代码。按建议导入不起作用。还有别的办法吗?我只测试了 JModelica 2.4 中的代码,它可能是一个错误?
希望就这两个问题提供一些意见。 / 简彼得
下面是对问题感兴趣的应用程序代码 d12_app7,然后是相关库 DEMO_v12。我已经为这两个问题标记了代码的注释更改,并且代码代表问题 1 alt 1.
encapsulated package d12_app7
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium7
import M2 = DEMO_v12.Medium2;
extends M2
(name = "Seven components" "Medium name",
nc = 7 "Number of substances",
mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight",
redeclare type Concentration = Real[nc] "Substance conc");
constant Integer C = 3 "Substance index";
constant Integer D = 4 "Substance index";
constant Integer E = 5 "Substance index";
constant Integer F = 6 "Substance index";
constant Integer G = 7 "Substance index";
end Medium7;
// ---------------------------------------------------------------------------------------------
// New sensor introduced in this application for measurement of substance A
// ---------------------------------------------------------------------------------------------
package Sensor7
connector LiquidCon
Medium7.Concentration c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
model SensorX
// import d12_app7.Equipment7.LiquidCon; // Question 2
import d12_app7.Medium7.*; // Question 1 - alt 1
constant Integer component = C; // Question 1 - alt 1
// constant Integer component = d12_app7.Medium7.A; // Question 1 - alt 2
LiquidCon probe;
RealOutput out;
equation
probe.F = 0;
out = probe.c[component];
end SensorX;
end Sensor7;
// ---------------------------------------------------------------------------------------------
// Adaptation of library DEMO_v12 to Medium7
// ---------------------------------------------------------------------------------------------
package Equipment7
import DEMO_v12.Equipment;
extends Equipment(redeclare package Medium=Medium7);
end Equipment7;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
import DEMO_v12.Control;
model Test
Equipment7.Medium medium; // Instance not necessary but helpful for user interface
Equipment7.PumpType pump;
Equipment7.FeedtankType feedtank;
Equipment7.HarvesttankType harvesttank;
Sensor7.SensorX sensor; // Question 1 alt 1 and 2
// Sensor7.SensorX sensor(component = medium.A); // Question 1 alt 3
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
connect(sensor.probe, harvesttank.port);
end Test;
end d12_app7;
最后是库代码DEMO_v12
package DEMO_v12
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium2
replaceable constant String name = "Two components" "Medium name";
replaceable constant Integer nc = 2 "Number of substances";
replaceable type Concentration = Real[nc] "Substance conc";
replaceable constant Real[nc] mw = {10, 20} "Substance weight";
constant Integer A = 1 "Substance index";
constant Integer B = 2 "Substance index";
end Medium2;
package Medium3
import M2 = DEMO_v12.Medium2;
extends M2
(name="Three components" "Medium name",
nc=3 "Number of substances",
mw = cat(1,M2.mw,{30}) "Substance weight",
redeclare type Concentration = Real[nc] "Substance conc");
constant Integer C = 3 "Substance index";
end Medium3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package Equipment
replaceable package Medium
end Medium;
connector LiquidCon
Medium.Concentration c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
model PumpType
LiquidCon inlet, outlet;
RealInput Fsp;
equation
inlet.F = Fsp;
connect(outlet, inlet);
end PumpType;
model FeedtankType
LiquidCon outlet;
constant Integer medium_nc = size(outlet.c,1);
parameter Real[medium_nc] c_in (each unit="kg/m3")
= {1.0*k for k in 1:medium_nc} "Feed inlet conc";
parameter Real V_0 (unit="m3") = 100 "Initial feed volume";
Real V(start=V_0, fixed=true, unit="m3") "Feed volume";
equation
for i in 1:medium_nc loop
outlet.c[i] = c_in[i];
end for;
der(V) = outlet.F;
end FeedtankType;
model HarvesttankType
LiquidCon inlet, port;
constant Integer medium_nc = size(inlet.c,1);
parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume";
parameter Real[medium_nc] m_0
(each unit="kg/m3") = zeros(medium_nc) "Initial substance mass";
Real[medium_nc] c "Substance conc";
Real[medium_nc] m
(start=m_0, each fixed=true) "Substance mass";
Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume";
equation
for i in 1:medium_nc loop
der(m[i]) = inlet.c[i]*inlet.F;
c[i] = m[i]/V;
port.c[i] = c[i];
end for;
der(V) = inlet.F;
end HarvesttankType;
end Equipment;
// ---------------------------------------------------------------------------------------------
// Control
// ---------------------------------------------------------------------------------------------
package Control
block FixValueType
RealOutput out;
parameter Real val=0;
equation
out = val;
end FixValueType;
end Control;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
// package Equipment3 = Equipment(redeclare package Medium=Medium3); // Just shorter version
package Equipment3
import DEMO_v12.Equipment;
extends Equipment(redeclare package Medium=Medium3);
end Equipment3;
model Test
Equipment3.Medium medium;
Equipment3.FeedtankType feedtank;
Equipment3.HarvesttankType harvesttank;
Equipment3.PumpType pump;
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
end Test;
end DEMO_v12;
我也在这个 post 最近得到了一些与 Modelon-JModelica 和 OpenModelica 相关的人的帮助 - 谢谢!下面的答案和评论以及更新的代码。
- 为了使 Medium7 的内容可用,我们(可能)可以按照提供的代码进行操作。在我的新代码中,我决定在配置测试模型之前不测量什么物质。因此,我在模型 SensorX 中声明了一个没有任何值的常量 Integer 组件。注意一个常量只能赋值一次。
- 为避免二次编写LiquidCon的代码,最好将传感器型号的代码放在适配Medium7的Equipment包的扩展中。
- 在模型测试中,我们需要访问组件的助记符。在 Modelica 中不允许在代码中使用包实例进行构造(但在 JModelica 和 OpenModelica 中仍然有效)。新代码中给出了一种普遍接受的方法。请注意,此解决方案使实际媒体的内容无法通过 FMU 访问。为了获得可访问性,本地实例需要由模型中的各种介质常量组成,就像名称一样。
- 我在 DEMO_v20.Medium2 中删除了常量前面的“可替换”,并且自 Modelica 3.2(但不是 3.1)以来,允许在 Medium3 中仅赋予这些 Medium 常量不同值的技术根据在之前的 post 回复中致 Hans Olsson。
- 我在 DEMO_v20 中引入了部分 MediumBase,然后 Medium2 从中扩展出来,MeiumBase 也是封装设备的形式参数 Medium 的约束类型。
该代码适用于 JModelica,既 运行 DEMO_v20 单独使用三种物质的测试示例,也适用于七种物质的应用程序代码。然而,在 OpenModelica 中,只有三种物质的测试示例有效。
希望能帮助代码在 OpenModelica 中运行并在 Dymolas 中检查它。
图书馆代码DEMO_v20
package DEMO_v20
// Here I have put together a small demo-library to illustrate questions
// around structuring handling of medium. The key structures are taken
// from MSL fluid, I think it is fair to say.
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
partial package MediumBase
constant String name "Medium name";
constant Integer nc "Number of substances";
replaceable type Concentration = Real[nc] "Substance conc";
end MediumBase;
package Medium2
extends MediumBase
(name="Two components",
nc=2);
constant Real[nc] mw = {10, 20} "Substance weight";
constant Integer A = 1 "Substance index";
constant Integer B = 2 "Substance index";
end Medium2;
package Medium3
import M2 = DEMO_v20.Medium2;
extends M2
(name="Three components" "Medium name",
nc=3 "Number of substances",
mw = cat(1,M2.mw,{30}) "Substance weight");
constant Integer C = 3 "Substance index";
end Medium3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package Equipment
replaceable package Medium = MediumBase
constrainedby MediumBase;
connector LiquidCon
Medium.Concentration c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
model PumpType
LiquidCon inlet, outlet;
RealInput Fsp;
equation
inlet.F = Fsp;
connect(outlet, inlet);
end PumpType;
model FeedtankType
LiquidCon outlet;
constant Integer medium_nc = size(outlet.c,1);
parameter Real[medium_nc] c_in (each unit="kg/m3")
= {1.0*k for k in 1:medium_nc} "Feed inlet conc";
parameter Real V_0 (unit="m3") = 100 "Initial feed volume";
Real V(start=V_0, fixed=true, unit="m3") "Feed volume";
equation
for i in 1:medium_nc loop
outlet.c[i] = c_in[i];
end for;
der(V) = outlet.F;
end FeedtankType;
model HarvesttankType
LiquidCon inlet, port;
constant Integer medium_nc = size(inlet.c,1);
parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume";
parameter Real[medium_nc] m_0
(each unit="kg/m3") = zeros(medium_nc) "Initial substance mass";
Real[medium_nc] c "Substance conc";
Real[medium_nc] m
(start=m_0, each fixed=true) "Substance mass";
Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume";
equation
for i in 1:medium_nc loop
der(m[i]) = inlet.c[i]*inlet.F;
c[i] = m[i]/V;
port.c[i] = c[i];
end for;
der(V) = inlet.F;
end HarvesttankType;
end Equipment;
// ---------------------------------------------------------------------------------------------
// Control
// ---------------------------------------------------------------------------------------------
package Control
block FixValueType
RealOutput out;
parameter Real val=0;
equation
out = val;
end FixValueType;
end Control;
// ---------------------------------------------------------------------------------------------
// Adaptation of package Equipment to Medium3
// ---------------------------------------------------------------------------------------------
package Equipment3
extends DEMO_v20.Equipment(redeclare package Medium=Medium3);
end Equipment3;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
model Test
package medium = DEMO_v20.Medium3; // Not accessible in FMU though
constant String name = medium.name; // But name here is accessible
Equipment3.FeedtankType feedtank;
Equipment3.HarvesttankType harvesttank;
Equipment3.PumpType pump;
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
end Test;
end DEMO_v20;
以及对应的申请代码d20_app7.mo
encapsulated package d20_app7
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium7
import M2 = DEMO_v20.Medium2;
extends M2
(name = "Seven components" "Medium name",
nc = 7 "Number of substances",
mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight");
constant Integer C = 3 "Substance index";
constant Integer D = 4 "Substance index";
constant Integer E = 5 "Substance index";
constant Integer F = 6 "Substance index";
constant Integer G = 7 "Substance index";
end Medium7;
// ---------------------------------------------------------------------------------------------
// Adaptation of library DEMO_v20 to Medium7 and including a new model SensorX
// ---------------------------------------------------------------------------------------------
package Equipment7
extends DEMO_v20.Equipment(redeclare package Medium=Medium7);
model SensorX
LiquidCon probe;
RealOutput out;
constant Integer component "Component measured";
equation
probe.F = 0;
out = probe.c[component];
end SensorX;
end Equipment7;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
import DEMO_v20.Control;
model Test
package medium = Medium7; // Not accessible in FMU though
constant String name = medium.name; // But name here is accessible
Equipment7.PumpType pump;
Equipment7.FeedtankType feedtank;
Equipment7.HarvesttankType harvesttank;
Equipment7.SensorX sensor(component = medium.G);
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
connect(sensor.probe, harvesttank.port);
end Test;
end d20_app7;
在 Dymola 版本 2018(64 位),2017-04-10 中测试了 DEMO_v20.mo
和 d20_app7.mo
。
加载文件DEMO_v20.mo
报错,
<medium declaration> (line 137, column 27: C:/Users/adeas31/Desktop/DEMO_v20.mo)
medium already declared on line 135.
并且运行 DEMO_v20.Test
给出,
Translation of DEMO_v20.Test:
For variable feedtank.medium_nc
declared in class DEMO_v20.Equipment.FeedtankType, C:/Users/adeas31/Desktop/DEMO_v20.mo at line 77, and used in component feedtank.
The variability of the definition equation:
feedtank.medium_nc = size(feedtank.outlet.c, 1);
is higher than the declared variability of the variables.
For variable harvesttank.medium_nc
declared in class DEMO_v20.Equipment.HarvesttankType, C:/Users/adeas31/Desktop/DEMO_v20.mo at line 91, and used in component harvesttank.
The variability of the definition equation:
harvesttank.medium_nc = size(harvesttank.inlet.c, 1);
is higher than the declared variability of the variables.
Basic type inconsistencies detected.
Translation aborted.
ERRORS have been issued.
运行 d20_app7.Test
给予,
Translation of d20_app7.Test:
Encapsulation of d20_app7
prevented us from finding DEMO_v20 in global scope.
Missing base class DEMO_v20.Equipment
the class DEMO_v20.Equipment exists, but Modelica is case-sensitive and uses scoping
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 46
Context: d20_app7.Equipment7
Component type specifier Equipment7.PumpType not found
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 67
Component context: pump
Component declared as Equipment7.PumpType pump in d20_app7.Test
Component type specifier Equipment7.FeedtankType not found
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 68
Component context: feedtank
Component declared as Equipment7.FeedtankType feedtank in d20_app7.Test
Component type specifier Equipment7.HarvesttankType not found
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 69
Component context: harvesttank
Component declared as Equipment7.HarvesttankType harvesttank in d20_app7.Test
Component type specifier LiquidCon not found
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 49
Component context: sensor.probe
Component declared as LiquidCon probe in d20_app7.Equipment7.SensorX
WARNINGS have been issued.
ERRORS have been issued.
希望对您有所帮助。
谢谢阿黛尔!
Dymola 错误日志让我对代码进行了以下更改:
- DEMO_v20 这里我去掉了 medium 的实例化 - 忘了看上面的 3)
- DEMO_v20 现在我从 Medium.nc 获取模型的大小,而不是通过连接器和 c 的大小。
- D20_app7这里我现在在package Equipment的适配过程中,先导入,再扩展适配Medium7。
更新后的代码 DEMO_v22 和 d22_app7 现在适用于 JModelica 和 OpenModelica。也可以在 Dymola 中进行测试
更新代码 DEMO_v22.mo
package DEMO_v22
// Here I have put together a small demo-library to illustrate questions
// around structuring handling of medium. The key structures are taken
// from MSL fluid, I think it is fair to say.
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
partial package MediumBase
constant String name "Medium name";
constant Integer nc "Number of substances";
replaceable type Concentration = Real[nc] "Substance conc";
end MediumBase;
package Medium2
extends MediumBase
(name="Two components",
nc=2);
constant Real[nc] mw = {10, 20} "Substance weight";
constant Integer A = 1 "Substance index";
constant Integer B = 2 "Substance index";
end Medium2;
package Medium3
import M2 = DEMO_v22.Medium2;
extends M2
(name="Three components" "Medium name",
nc=3 "Number of substances",
mw = cat(1,M2.mw,{30}) "Substance weight");
constant Integer C = 3 "Substance index";
end Medium3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package Equipment
replaceable package Medium = MediumBase
constrainedby MediumBase;
connector LiquidCon
Medium.Concentration c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
model PumpType
LiquidCon inlet, outlet;
RealInput Fsp;
equation
inlet.F = Fsp;
connect(outlet, inlet);
end PumpType;
model FeedtankType
LiquidCon outlet;
parameter Real[Medium.nc] c_in (each unit="kg/m3")
= {1.0*k for k in 1:Medium.nc} "Feed inlet conc";
parameter Real V_0 (unit="m3") = 100 "Initial feed volume";
Real V(start=V_0, fixed=true, unit="m3") "Feed volume";
equation
for i in 1:Medium.nc loop
outlet.c[i] = c_in[i];
end for;
der(V) = outlet.F;
end FeedtankType;
model HarvesttankType
LiquidCon inlet, port;
parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume";
parameter Real[Medium.nc] m_0
(each unit="kg/m3") = zeros(Medium.nc) "Initial substance mass";
Real[Medium.nc] c "Substance conc";
Real[Medium.nc] m
(start=m_0, each fixed=true) "Substance mass";
Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume";
equation
for i in 1:Medium.nc loop
der(m[i]) = inlet.c[i]*inlet.F;
c[i] = m[i]/V;
port.c[i] = c[i];
end for;
der(V) = inlet.F;
end HarvesttankType;
end Equipment;
// ---------------------------------------------------------------------------------------------
// Control
// ---------------------------------------------------------------------------------------------
package Control
block FixValueType
RealOutput out;
parameter Real val=0;
equation
out = val;
end FixValueType;
end Control;
// ---------------------------------------------------------------------------------------------
// Adaptation of package Equipment to Medium3
// ---------------------------------------------------------------------------------------------
package Equipment3
extends DEMO_v22.Equipment(redeclare package Medium=Medium3);
end Equipment3;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
model Test
package medium = DEMO_v22.Medium3; // Not accessible in FMU though
constant String name = medium.name; // But name here is now accessible
Equipment3.FeedtankType feedtank;
Equipment3.HarvesttankType harvesttank;
Equipment3.PumpType pump;
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
end Test;
end DEMO_v22;
并更新了应用程序代码 d22_app7.mo
encapsulated package d22_app7
// Here I put together an application for 7 substances - print 8 pt
// and import code from the library DEMO.
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium7
import M2 = DEMO_v22.Medium2;
extends M2
(name = "Seven components" "Medium name",
nc = 7 "Number of substances",
mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight");
constant Integer C = 3 "Substance index";
constant Integer D = 4 "Substance index";
constant Integer E = 5 "Substance index";
constant Integer F = 6 "Substance index";
constant Integer G = 7 "Substance index";
end Medium7;
// ---------------------------------------------------------------------------------------------
// Adaptation of library DEMO_v22 to Medium7 and including a new model SensorX
// ---------------------------------------------------------------------------------------------
package Equipment7
import DEMO_v22.Equipment;
extends Equipment(redeclare package Medium=Medium7);
model SensorX
LiquidCon probe;
RealOutput out;
constant Integer component "Component measured";
equation
probe.F = 0;
out = probe.c[component];
end SensorX;
end Equipment7;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
import DEMO_v22.Control;
model Test
package medium = Medium7; // Not accessible in FMU though
constant String name = medium.name; // But name here is accessible
Equipment7.PumpType pump;
Equipment7.FeedtankType feedtank;
Equipment7.HarvesttankType harvesttank;
Equipment7.SensorX sensor(component = medium.G);
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
connect(sensor.probe, harvesttank.port);
end Test;
end d22_app7;
我继续努力了解如何最好地划分库和应用程序中的代码。在之前的几篇文章中,我使用了带有应用程序 dxx_app7 的玩具示例 DEMO_xx 库。下面是一个稍微更新的版本来解决这里的问题。我已经包括了在收获箱中添加传感器的可能性。
现在我想了解如何在应用程序代码中引入从库 Medium2 扩展而来的应用程序 Medium7 的信息,并在应用程序的新组件模型中充分使用这些信息。
我的理解是,如果你导入一个从另一个包扩展的包,你只会得到什么是“最新”包,而不是通过扩展构建的包以及聚合的总 Medium7 信息。
示例中通过将常量 SensorX.component 从有效的 C 更改为无效的 A 或 B 来说明这一事实。
但是,如果我创建一个 Medium7 的本地实例,那么我将获得 Medium7 的完整信息。我可以在 SensorX 中按照标记为问题 1 - 替代 2 的方式执行此操作。 我也可以在系统配置中选择基板来测量并标记问题 1 alt 3。我认为这是更具可读性的代码。
但是我如何让 Medium7 的所有内容在本地可用?我是否必须像我在此处使用 sensorX.component 显示的那样,为我需要的每个常量在本地定义一个新常量?通常,您可能希望在模型中访问介质的各种属性,并且方便放入包 Medium
我也希望我可以导入一个适用于 Medium7 的连接器 LiquidCon,而不是在 Sensor7 包中再次编写该代码。按建议导入不起作用。还有别的办法吗?我只测试了 JModelica 2.4 中的代码,它可能是一个错误?
希望就这两个问题提供一些意见。 / 简彼得
下面是对问题感兴趣的应用程序代码 d12_app7,然后是相关库 DEMO_v12。我已经为这两个问题标记了代码的注释更改,并且代码代表问题 1 alt 1.
encapsulated package d12_app7
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium7
import M2 = DEMO_v12.Medium2;
extends M2
(name = "Seven components" "Medium name",
nc = 7 "Number of substances",
mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight",
redeclare type Concentration = Real[nc] "Substance conc");
constant Integer C = 3 "Substance index";
constant Integer D = 4 "Substance index";
constant Integer E = 5 "Substance index";
constant Integer F = 6 "Substance index";
constant Integer G = 7 "Substance index";
end Medium7;
// ---------------------------------------------------------------------------------------------
// New sensor introduced in this application for measurement of substance A
// ---------------------------------------------------------------------------------------------
package Sensor7
connector LiquidCon
Medium7.Concentration c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
model SensorX
// import d12_app7.Equipment7.LiquidCon; // Question 2
import d12_app7.Medium7.*; // Question 1 - alt 1
constant Integer component = C; // Question 1 - alt 1
// constant Integer component = d12_app7.Medium7.A; // Question 1 - alt 2
LiquidCon probe;
RealOutput out;
equation
probe.F = 0;
out = probe.c[component];
end SensorX;
end Sensor7;
// ---------------------------------------------------------------------------------------------
// Adaptation of library DEMO_v12 to Medium7
// ---------------------------------------------------------------------------------------------
package Equipment7
import DEMO_v12.Equipment;
extends Equipment(redeclare package Medium=Medium7);
end Equipment7;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
import DEMO_v12.Control;
model Test
Equipment7.Medium medium; // Instance not necessary but helpful for user interface
Equipment7.PumpType pump;
Equipment7.FeedtankType feedtank;
Equipment7.HarvesttankType harvesttank;
Sensor7.SensorX sensor; // Question 1 alt 1 and 2
// Sensor7.SensorX sensor(component = medium.A); // Question 1 alt 3
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
connect(sensor.probe, harvesttank.port);
end Test;
end d12_app7;
最后是库代码DEMO_v12
package DEMO_v12
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium2
replaceable constant String name = "Two components" "Medium name";
replaceable constant Integer nc = 2 "Number of substances";
replaceable type Concentration = Real[nc] "Substance conc";
replaceable constant Real[nc] mw = {10, 20} "Substance weight";
constant Integer A = 1 "Substance index";
constant Integer B = 2 "Substance index";
end Medium2;
package Medium3
import M2 = DEMO_v12.Medium2;
extends M2
(name="Three components" "Medium name",
nc=3 "Number of substances",
mw = cat(1,M2.mw,{30}) "Substance weight",
redeclare type Concentration = Real[nc] "Substance conc");
constant Integer C = 3 "Substance index";
end Medium3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package Equipment
replaceable package Medium
end Medium;
connector LiquidCon
Medium.Concentration c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
model PumpType
LiquidCon inlet, outlet;
RealInput Fsp;
equation
inlet.F = Fsp;
connect(outlet, inlet);
end PumpType;
model FeedtankType
LiquidCon outlet;
constant Integer medium_nc = size(outlet.c,1);
parameter Real[medium_nc] c_in (each unit="kg/m3")
= {1.0*k for k in 1:medium_nc} "Feed inlet conc";
parameter Real V_0 (unit="m3") = 100 "Initial feed volume";
Real V(start=V_0, fixed=true, unit="m3") "Feed volume";
equation
for i in 1:medium_nc loop
outlet.c[i] = c_in[i];
end for;
der(V) = outlet.F;
end FeedtankType;
model HarvesttankType
LiquidCon inlet, port;
constant Integer medium_nc = size(inlet.c,1);
parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume";
parameter Real[medium_nc] m_0
(each unit="kg/m3") = zeros(medium_nc) "Initial substance mass";
Real[medium_nc] c "Substance conc";
Real[medium_nc] m
(start=m_0, each fixed=true) "Substance mass";
Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume";
equation
for i in 1:medium_nc loop
der(m[i]) = inlet.c[i]*inlet.F;
c[i] = m[i]/V;
port.c[i] = c[i];
end for;
der(V) = inlet.F;
end HarvesttankType;
end Equipment;
// ---------------------------------------------------------------------------------------------
// Control
// ---------------------------------------------------------------------------------------------
package Control
block FixValueType
RealOutput out;
parameter Real val=0;
equation
out = val;
end FixValueType;
end Control;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
// package Equipment3 = Equipment(redeclare package Medium=Medium3); // Just shorter version
package Equipment3
import DEMO_v12.Equipment;
extends Equipment(redeclare package Medium=Medium3);
end Equipment3;
model Test
Equipment3.Medium medium;
Equipment3.FeedtankType feedtank;
Equipment3.HarvesttankType harvesttank;
Equipment3.PumpType pump;
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
end Test;
end DEMO_v12;
我也在这个 post 最近得到了一些与 Modelon-JModelica 和 OpenModelica 相关的人的帮助 - 谢谢!下面的答案和评论以及更新的代码。
- 为了使 Medium7 的内容可用,我们(可能)可以按照提供的代码进行操作。在我的新代码中,我决定在配置测试模型之前不测量什么物质。因此,我在模型 SensorX 中声明了一个没有任何值的常量 Integer 组件。注意一个常量只能赋值一次。
- 为避免二次编写LiquidCon的代码,最好将传感器型号的代码放在适配Medium7的Equipment包的扩展中。
- 在模型测试中,我们需要访问组件的助记符。在 Modelica 中不允许在代码中使用包实例进行构造(但在 JModelica 和 OpenModelica 中仍然有效)。新代码中给出了一种普遍接受的方法。请注意,此解决方案使实际媒体的内容无法通过 FMU 访问。为了获得可访问性,本地实例需要由模型中的各种介质常量组成,就像名称一样。
- 我在 DEMO_v20.Medium2 中删除了常量前面的“可替换”,并且自 Modelica 3.2(但不是 3.1)以来,允许在 Medium3 中仅赋予这些 Medium 常量不同值的技术根据在之前的 post 回复中致 Hans Olsson。
- 我在 DEMO_v20 中引入了部分 MediumBase,然后 Medium2 从中扩展出来,MeiumBase 也是封装设备的形式参数 Medium 的约束类型。
该代码适用于 JModelica,既 运行 DEMO_v20 单独使用三种物质的测试示例,也适用于七种物质的应用程序代码。然而,在 OpenModelica 中,只有三种物质的测试示例有效。
希望能帮助代码在 OpenModelica 中运行并在 Dymolas 中检查它。
图书馆代码DEMO_v20
package DEMO_v20
// Here I have put together a small demo-library to illustrate questions
// around structuring handling of medium. The key structures are taken
// from MSL fluid, I think it is fair to say.
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
partial package MediumBase
constant String name "Medium name";
constant Integer nc "Number of substances";
replaceable type Concentration = Real[nc] "Substance conc";
end MediumBase;
package Medium2
extends MediumBase
(name="Two components",
nc=2);
constant Real[nc] mw = {10, 20} "Substance weight";
constant Integer A = 1 "Substance index";
constant Integer B = 2 "Substance index";
end Medium2;
package Medium3
import M2 = DEMO_v20.Medium2;
extends M2
(name="Three components" "Medium name",
nc=3 "Number of substances",
mw = cat(1,M2.mw,{30}) "Substance weight");
constant Integer C = 3 "Substance index";
end Medium3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package Equipment
replaceable package Medium = MediumBase
constrainedby MediumBase;
connector LiquidCon
Medium.Concentration c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
model PumpType
LiquidCon inlet, outlet;
RealInput Fsp;
equation
inlet.F = Fsp;
connect(outlet, inlet);
end PumpType;
model FeedtankType
LiquidCon outlet;
constant Integer medium_nc = size(outlet.c,1);
parameter Real[medium_nc] c_in (each unit="kg/m3")
= {1.0*k for k in 1:medium_nc} "Feed inlet conc";
parameter Real V_0 (unit="m3") = 100 "Initial feed volume";
Real V(start=V_0, fixed=true, unit="m3") "Feed volume";
equation
for i in 1:medium_nc loop
outlet.c[i] = c_in[i];
end for;
der(V) = outlet.F;
end FeedtankType;
model HarvesttankType
LiquidCon inlet, port;
constant Integer medium_nc = size(inlet.c,1);
parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume";
parameter Real[medium_nc] m_0
(each unit="kg/m3") = zeros(medium_nc) "Initial substance mass";
Real[medium_nc] c "Substance conc";
Real[medium_nc] m
(start=m_0, each fixed=true) "Substance mass";
Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume";
equation
for i in 1:medium_nc loop
der(m[i]) = inlet.c[i]*inlet.F;
c[i] = m[i]/V;
port.c[i] = c[i];
end for;
der(V) = inlet.F;
end HarvesttankType;
end Equipment;
// ---------------------------------------------------------------------------------------------
// Control
// ---------------------------------------------------------------------------------------------
package Control
block FixValueType
RealOutput out;
parameter Real val=0;
equation
out = val;
end FixValueType;
end Control;
// ---------------------------------------------------------------------------------------------
// Adaptation of package Equipment to Medium3
// ---------------------------------------------------------------------------------------------
package Equipment3
extends DEMO_v20.Equipment(redeclare package Medium=Medium3);
end Equipment3;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
model Test
package medium = DEMO_v20.Medium3; // Not accessible in FMU though
constant String name = medium.name; // But name here is accessible
Equipment3.FeedtankType feedtank;
Equipment3.HarvesttankType harvesttank;
Equipment3.PumpType pump;
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
end Test;
end DEMO_v20;
以及对应的申请代码d20_app7.mo
encapsulated package d20_app7
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium7
import M2 = DEMO_v20.Medium2;
extends M2
(name = "Seven components" "Medium name",
nc = 7 "Number of substances",
mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight");
constant Integer C = 3 "Substance index";
constant Integer D = 4 "Substance index";
constant Integer E = 5 "Substance index";
constant Integer F = 6 "Substance index";
constant Integer G = 7 "Substance index";
end Medium7;
// ---------------------------------------------------------------------------------------------
// Adaptation of library DEMO_v20 to Medium7 and including a new model SensorX
// ---------------------------------------------------------------------------------------------
package Equipment7
extends DEMO_v20.Equipment(redeclare package Medium=Medium7);
model SensorX
LiquidCon probe;
RealOutput out;
constant Integer component "Component measured";
equation
probe.F = 0;
out = probe.c[component];
end SensorX;
end Equipment7;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
import DEMO_v20.Control;
model Test
package medium = Medium7; // Not accessible in FMU though
constant String name = medium.name; // But name here is accessible
Equipment7.PumpType pump;
Equipment7.FeedtankType feedtank;
Equipment7.HarvesttankType harvesttank;
Equipment7.SensorX sensor(component = medium.G);
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
connect(sensor.probe, harvesttank.port);
end Test;
end d20_app7;
在 Dymola 版本 2018(64 位),2017-04-10 中测试了 DEMO_v20.mo
和 d20_app7.mo
。
加载文件DEMO_v20.mo
报错,
<medium declaration> (line 137, column 27: C:/Users/adeas31/Desktop/DEMO_v20.mo)
medium already declared on line 135.
并且运行 DEMO_v20.Test
给出,
Translation of DEMO_v20.Test:
For variable feedtank.medium_nc
declared in class DEMO_v20.Equipment.FeedtankType, C:/Users/adeas31/Desktop/DEMO_v20.mo at line 77, and used in component feedtank.
The variability of the definition equation:
feedtank.medium_nc = size(feedtank.outlet.c, 1);
is higher than the declared variability of the variables.
For variable harvesttank.medium_nc
declared in class DEMO_v20.Equipment.HarvesttankType, C:/Users/adeas31/Desktop/DEMO_v20.mo at line 91, and used in component harvesttank.
The variability of the definition equation:
harvesttank.medium_nc = size(harvesttank.inlet.c, 1);
is higher than the declared variability of the variables.
Basic type inconsistencies detected.
Translation aborted.
ERRORS have been issued.
运行 d20_app7.Test
给予,
Translation of d20_app7.Test:
Encapsulation of d20_app7
prevented us from finding DEMO_v20 in global scope.
Missing base class DEMO_v20.Equipment
the class DEMO_v20.Equipment exists, but Modelica is case-sensitive and uses scoping
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 46
Context: d20_app7.Equipment7
Component type specifier Equipment7.PumpType not found
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 67
Component context: pump
Component declared as Equipment7.PumpType pump in d20_app7.Test
Component type specifier Equipment7.FeedtankType not found
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 68
Component context: feedtank
Component declared as Equipment7.FeedtankType feedtank in d20_app7.Test
Component type specifier Equipment7.HarvesttankType not found
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 69
Component context: harvesttank
Component declared as Equipment7.HarvesttankType harvesttank in d20_app7.Test
Component type specifier LiquidCon not found
File: C:/Users/adeas31/Desktop/d20_app7.mo, line 49
Component context: sensor.probe
Component declared as LiquidCon probe in d20_app7.Equipment7.SensorX
WARNINGS have been issued.
ERRORS have been issued.
希望对您有所帮助。
谢谢阿黛尔! Dymola 错误日志让我对代码进行了以下更改:
- DEMO_v20 这里我去掉了 medium 的实例化 - 忘了看上面的 3)
- DEMO_v20 现在我从 Medium.nc 获取模型的大小,而不是通过连接器和 c 的大小。
- D20_app7这里我现在在package Equipment的适配过程中,先导入,再扩展适配Medium7。
更新后的代码 DEMO_v22 和 d22_app7 现在适用于 JModelica 和 OpenModelica。也可以在 Dymola 中进行测试
更新代码 DEMO_v22.mo
package DEMO_v22
// Here I have put together a small demo-library to illustrate questions
// around structuring handling of medium. The key structures are taken
// from MSL fluid, I think it is fair to say.
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
partial package MediumBase
constant String name "Medium name";
constant Integer nc "Number of substances";
replaceable type Concentration = Real[nc] "Substance conc";
end MediumBase;
package Medium2
extends MediumBase
(name="Two components",
nc=2);
constant Real[nc] mw = {10, 20} "Substance weight";
constant Integer A = 1 "Substance index";
constant Integer B = 2 "Substance index";
end Medium2;
package Medium3
import M2 = DEMO_v22.Medium2;
extends M2
(name="Three components" "Medium name",
nc=3 "Number of substances",
mw = cat(1,M2.mw,{30}) "Substance weight");
constant Integer C = 3 "Substance index";
end Medium3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package Equipment
replaceable package Medium = MediumBase
constrainedby MediumBase;
connector LiquidCon
Medium.Concentration c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
model PumpType
LiquidCon inlet, outlet;
RealInput Fsp;
equation
inlet.F = Fsp;
connect(outlet, inlet);
end PumpType;
model FeedtankType
LiquidCon outlet;
parameter Real[Medium.nc] c_in (each unit="kg/m3")
= {1.0*k for k in 1:Medium.nc} "Feed inlet conc";
parameter Real V_0 (unit="m3") = 100 "Initial feed volume";
Real V(start=V_0, fixed=true, unit="m3") "Feed volume";
equation
for i in 1:Medium.nc loop
outlet.c[i] = c_in[i];
end for;
der(V) = outlet.F;
end FeedtankType;
model HarvesttankType
LiquidCon inlet, port;
parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume";
parameter Real[Medium.nc] m_0
(each unit="kg/m3") = zeros(Medium.nc) "Initial substance mass";
Real[Medium.nc] c "Substance conc";
Real[Medium.nc] m
(start=m_0, each fixed=true) "Substance mass";
Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume";
equation
for i in 1:Medium.nc loop
der(m[i]) = inlet.c[i]*inlet.F;
c[i] = m[i]/V;
port.c[i] = c[i];
end for;
der(V) = inlet.F;
end HarvesttankType;
end Equipment;
// ---------------------------------------------------------------------------------------------
// Control
// ---------------------------------------------------------------------------------------------
package Control
block FixValueType
RealOutput out;
parameter Real val=0;
equation
out = val;
end FixValueType;
end Control;
// ---------------------------------------------------------------------------------------------
// Adaptation of package Equipment to Medium3
// ---------------------------------------------------------------------------------------------
package Equipment3
extends DEMO_v22.Equipment(redeclare package Medium=Medium3);
end Equipment3;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
model Test
package medium = DEMO_v22.Medium3; // Not accessible in FMU though
constant String name = medium.name; // But name here is now accessible
Equipment3.FeedtankType feedtank;
Equipment3.HarvesttankType harvesttank;
Equipment3.PumpType pump;
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
end Test;
end DEMO_v22;
并更新了应用程序代码 d22_app7.mo
encapsulated package d22_app7
// Here I put together an application for 7 substances - print 8 pt
// and import code from the library DEMO.
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium7
import M2 = DEMO_v22.Medium2;
extends M2
(name = "Seven components" "Medium name",
nc = 7 "Number of substances",
mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight");
constant Integer C = 3 "Substance index";
constant Integer D = 4 "Substance index";
constant Integer E = 5 "Substance index";
constant Integer F = 6 "Substance index";
constant Integer G = 7 "Substance index";
end Medium7;
// ---------------------------------------------------------------------------------------------
// Adaptation of library DEMO_v22 to Medium7 and including a new model SensorX
// ---------------------------------------------------------------------------------------------
package Equipment7
import DEMO_v22.Equipment;
extends Equipment(redeclare package Medium=Medium7);
model SensorX
LiquidCon probe;
RealOutput out;
constant Integer component "Component measured";
equation
probe.F = 0;
out = probe.c[component];
end SensorX;
end Equipment7;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
import DEMO_v22.Control;
model Test
package medium = Medium7; // Not accessible in FMU though
constant String name = medium.name; // But name here is accessible
Equipment7.PumpType pump;
Equipment7.FeedtankType feedtank;
Equipment7.HarvesttankType harvesttank;
Equipment7.SensorX sensor(component = medium.G);
Control.FixValueType Fsp(val=0.2);
equation
connect(feedtank.outlet, pump.inlet);
connect(pump.outlet, harvesttank.inlet);
connect(Fsp.out, pump.Fsp);
connect(sensor.probe, harvesttank.port);
end Test;
end d22_app7;