帖子状态:
200313 得到了代码 DEMO_v42 的答案,我接受了赏金!
200310 我评论了昨天建议的两篇关键论文。还是不明白如何更新DEMO_v41。
200309 我想强调的是,关键问题是如何在代码DEMO_v41(如果可能的话)中引入流的概念,并以此方式使连接器平衡。作为浓度的变量 c 应该声明为流,但是应该如何使用 inStream 或actualStream 更新方程 - 我很高兴看到!
200226 添加了帖子示例 DEMO_v41,它是一个简化版本,我希望比第一个 DEMO_v40 更具可读性。
200225 我对给出的答案提出了一些评论,并试图让读者将注意力集中在实际问题上,但收效甚微。
200224 我在这篇文章中得到了一些一般和详细的意见。详细的评论价值较低,部分原因是对问题的误解。雷内(Rene)的更笼统的答案很好,但太笼统了。在我考虑使用 Modelica.Media 等之前,我真的很喜欢通过小例子来了解如何使用流的概念。这是一个学习过程。
我想知道如何正确定义液体的连接器,该液体在溶液中含有多种不同浓度的成分,然后该溶液具有流速。液体中的压力可以忽略不计。
我长期使用的标准连接器是:
connector LiquidCon
nc=5;
Real c[nc] “Component concentrations”;
flow Real F “Flow rate”;
end LiquidCon;
连接器在 JModelica 和 OpenModelica 中运行良好,但我在 OpenModelica 中收到连接器不平衡的警告。在 Modelica 语言规范第 9.3.1 节中,我发现我的构造实际上不合法,请参阅https://www.modelica.org/documents/ModelicaSpec34.pdf https://www.modelica.org/documents/ModelicaSpec34.pdf。如何制作出满足要求的连接器?
我花了一些时间阅读 Fritzons 书籍第 2n 版中关于“流”概念的第 5.10 章,但我需要更详细地研究它。
我的简单连接器带来警告的原因是,当您声明流变量时,编译器假定另一个变量是该流变量的潜在变量,即连接器中至少流和潜在变量的数量必须相同。当然,在我的例子中,成分浓度不是一个潜在的变量,而是编译器无法检测到的。
在第 5.10 章的介绍部分中,“流”概念的范围似乎是“……具有相关属性的双向物质流的应用……”。在我的应用领域,我怀疑我是否需要考虑双向流。这意味着使用流是一种“杀伤力”。但这似乎也暗示着我也不应该使用“流”这个概念,这有点可惜。我们真的应该停止使用“流”这个概念吗? ?
不管怎样,我试图整理一个比 Fritzson 书中关于这个主题的更基本的例子,看看“流”概念的使用会是什么样子,以及计算时间等方面的开销。在下面的示例中,我模拟了从进料罐到收获罐的液体流动。现在流量由压力差控制。代码 DEMO_v41 有效并发出连接器不平衡的警告。如果我现在将底物浓度 c 声明为“流”,那么我现在应该如何使用 inStream 和actualStream 更新代码,使其以相同的方式工作,但现在使用这个平衡连接器?
package DEMO_v41
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
// ---------------------------------------------------------------------------------------------
// Equipment
// ---------------------------------------------------------------------------------------------
package EquipmentLib
connector LiquidCon
Real P "Pressure";
flow Real F "Flow rate";
Real c "Substance conc";
end LiquidCon;
model PipeType
LiquidCon inlet, outlet;
parameter Real area = 1;
equation
inlet.F = -outlet.F;
outlet.F = -area^2*(inlet.P - outlet.P); // Linearized Bernoulli equation
outlet.c = inlet.c;
end PipeType;
model FeedtankType
LiquidCon outlet;
parameter Real P = 0.1 "Pressure";
parameter Real V_0 = 100 "Initial feed volume";
parameter Real c_in = 1.0 "Feedtank conc";
Real V(start=V_0, fixed=true) "Feed volume";
equation
outlet.c = c_in;
outlet.P = P;
der(V) = outlet.F;
end FeedtankType;
model HarvesttankType
LiquidCon inlet;
parameter Real P = 0.0 "Pressure";
parameter Real V_0 = 1.0 "Initial harvest liquid volume";
parameter Real m_0 = 0.0 "Initial substance mass";
Real V(start=V_0, fixed=true) "Harvest liquid volume";
Real m(start=m_0, fixed=true) "Substance mass";
Real c "Substance conc";
equation
inlet.P = P;
der(V) = inlet.F;
der(m) = inlet.c*inlet.F;
c = m/V;
end HarvesttankType;
end EquipmentLib;
// ---------------------------------------------------------------------------------------------
// Example of system
// ---------------------------------------------------------------------------------------------
model Test
EquipmentLib.FeedtankType feedtank;
EquipmentLib.HarvesttankType harvesttank;
EquipmentLib.PipeType pipe;
equation
connect(feedtank.outlet, pipe.inlet);
connect(pipe.outlet, harvesttank.inlet);
end Test;
end DEMO_v41;
下面的旧示例 DEMO_v40 更通用,更难阅读,但由于围绕此示例的一个早期答案,因此保留作为参考。
我得到的编译(JModelica 2.14)错误消息是:“扁平化模型中的错误:系统在结构上是单一的。以下变量无法与方程匹配:harvestank.inlet.c[1]、pipe.outlet.c[1]。 OpenModelica (1.16) 给出了大致相同的消息。这里有什么问题吗?
package DEMO_v40
// ---------------------------------------------------------------------------------------------
// 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 Medium1
extends MediumBase
(name="One component medium",
nc=1);
constant Real[nc] mw = {10} "Substance weight";
constant Integer A = 1 "Substance index";
end Medium1;
record Medium_data
constant String name = Medium1.name;
constant Integer nc = Medium1.nc;
constant Real[nc] mw = Medium1.mw;
constant Integer A = Medium1.A;
end Medium_data;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package EquipmentLib
replaceable package Medium = MediumBase // formal parameter - EquipmentLib
constrainedby MediumBase;
connector LiquidCon
Real P "Pressure";
flow Real F (unit="m3/s") "Flow rate";
stream Medium.Concentration c "Substance conc";
end LiquidCon;
model PipeType
LiquidCon inlet, outlet;
parameter Real area = 1;
equation
inlet.F = -outlet.F;
outlet.F = area^2*(inlet.P - outlet.P); // Linearized Bernoulli equation
for i in 1:Medium.nc loop
outlet.c[i] = inlet.c[i];
end for;
end PipeType;
model FeedtankType
LiquidCon outlet;
parameter Real P = 0.1 "Pressure";
parameter Real V_0 (unit="m3") = 100 "Initial feed volume";
parameter Real[Medium.nc] c_in (each unit="kg/m3")
= {1.0*k for k in 1:Medium.nc} "Feed inlet conc";
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;
outlet.P = P;
der(V) = outlet.F;
end FeedtankType;
model HarvesttankType
LiquidCon inlet;
parameter Real P = 0.0 "Pressure";
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[Medium.nc] c "Substance conc";
Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume";
equation
inlet.P = P;
der(V) = inlet.F;
for i in 1:Medium.nc loop
der(m[i]) = inStream(inlet.c[i])*inlet.F;
c[i] = m[i]/V;
end for;
end HarvesttankType;
end EquipmentLib;
// ---------------------------------------------------------------------------------------------
// Adaptation of package Equipment to Medium1
// ---------------------------------------------------------------------------------------------
package Equipment
import DEMO_v40.EquipmentLib;
extends EquipmentLib(redeclare package Medium=Medium1);
end Equipment;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
model Test
Medium_data medium;
Equipment.FeedtankType feedtank;
Equipment.HarvesttankType harvesttank;
Equipment.PipeType pipe;
equation
connect(feedtank.outlet, pipe.inlet);
connect(pipe.outlet, harvesttank.inlet);
end Test;
end DEMO_v40;