我认为,要以安全的方式对库包进行参数化,您可以使灵活性尽可能“小”。您可以在包中拥有一个常量整数 nc,您在调整包时将其指定为 Medium3.nc。然后在 Equipment 包内定义了连接器 LiquidCon,并将浓度向量声明为 Real [nc] c;除了 nc 之外,关于 Medium 的其他信息可以在配置级别上带到应用程序测试中,而不是作为设备包的改编,在这个例子中没有讨论,而是在其他相关帖子中讨论。通过这种方式,包适应过程将尽可能“安全”。
涉及将 ReactionType 引入 HarvesttankType(现在已适应实际的 nc)的其他适应需要非常灵活,以使该库包具有任何兴趣。我们对 ReactionType 的要求是具有接口:outer Real(nc] c, q; 并且我们可以在部分模型中描述并使用 constrainedby 构造,以带来一些安全性。
请参阅下面的代码 DEMO_v17_alt1 和 d17_alt1_app7。
但是,我更愿意将代码编写为 alt2 并保留 ReactionType 等仅为 HarvesttankType 而不是整个 Equipment 包定义。这将需要允许对库进行两步调整。第一级使设备适应介质组件的数量。第二级使现在适应的 HarvesttankType 适应 ReactionType。这在 JModelica 中是不可能的,但实际上在 OpenModelica 中是不可能的。
所以只有 alt1 在 JModelica 2.4 中有效,而 alt1 和 alt2 在 OpenModelica 1.13.2(和 1.14 beta)中有效。当前的 Modelica 定义说明了什么?
库代码 DEMO_v17_alt1:
package DEMO_v17_alt1
// 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;
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_v17_alt1.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;
model Reaction3
constant Integer nc = 3;
outer Real[nc] c;
outer Real[nc] q;
equation
q[1] = 0;
q[2] = 0;
q[3] =-c[3];
end Reaction3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package Equipment
constant Integer nc;
connector LiquidCon
Real[nc] c "Substance conc";
flow Real F (unit="m3/s") "Flow rate";
end LiquidCon;
replaceable model ReactionType = NoReaction // Alternative 1
constrainedby ReactionTypeInterface;
partial model ReactionTypeInterface // Alternative 1
outer Real[nc] c, q;
end ReactionTypeInterface;
model NoReaction // Alternative 1
extends ReactionTypeInterface;
equation
for i in 1:nc loop
q[i] = 0;
end for;
end NoReaction;
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
// Connection to reaction
// replaceable model ReactionType = NoReaction constrainedby ReactionTypeInterface; // Alternative 2
ReactionType reaction;
inner Real[medium_nc] c "Substance conc";
inner Real[medium_nc] q "Reaction rate";
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] 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 + q[i];
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 library DEMO_v17_alt1 to Medium3 and Reaction3
// ---------------------------------------------------------------------------------------------
package Equipment3 // Alternative 1
import DEMO_v17_alt1.Equipment;
extends Equipment(nc=Medium3.nc,
redeclare model ReactionType=Reaction3);
end Equipment3;
// package Equipment3 // Alternative 2
// import DEMO_v17_alt2.Equipment;
// extends Equipment(nc=3);
// end Equipment3;
// model HarvesttankType3
// import DEMO_v17_alt2.Equipment3.HarvesttankType;
// extends HarvesttankType(redeclare model ReactionType=Reaction3);
// end HarvesttankType3;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
model Test
Medium3 medium;
Equipment3.FeedtankType feedtank;
Equipment3.HarvesttankType harvesttank; // Alternative 1
// HarvesttankType3 harvesttank; // Alternative 2
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_v17_alt1;
和应用程序代码 d17_alt1_app7
encapsulated package d17_alt1_app7
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
package Medium7
import M2 = DEMO_v17_alt1.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;
model Reaction7
constant Integer nc = 7;
outer Real[nc] c;
outer Real[nc] q;
equation
q[1] = 0;
q[2] = 0;
q[3] = 0;
q[4] = 0;
q[5] = 0;
q[6] = 0;
q[7] =-c[7];
end Reaction7;
// ---------------------------------------------------------------------------------------------
// Adaptation of library DEMO_v17_alt1 to Medium7 and Reaction7
// ---------------------------------------------------------------------------------------------
package Equipment7
import DEMO_v17_alt1.Equipment;
extends Equipment(nc=Medium7.nc,
redeclare model ReactionType=Reaction7);
end Equipment7;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
import DEMO_v17_alt1.Control;
model Test
Medium7 medium; // Instance not necessary but helpful for user interface
Equipment7.PumpType pump;
Equipment7.FeedtankType feedtank;
Equipment7.HarvesttankType harvesttank;
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 d17_alt1_app7;