具有模式相关参数的重复组件
Repeated components with pattern dependent parameters
想象有一个重复的组件模式(例如,动态管道),它有一个参数(例如,长度),该参数将根据它在模式中的位置而改变。我建议可以通过在感兴趣的参数之前省略 "each" 前缀来实现。
例如。让我们拿 n 个管道并按以下方式将它们添加到模型中:
parameter Integer n;
Modelica.Fluid.Pipes.DynamicPipe[n] pipe;
对于一个非常简单的示例,让我们指定我们希望模式中第一个管道的长度具有一定长度 (length_1),而所有其他管道具有 length_n。我的想法是,可以在按以下方式定义参数时放置一个 if 语句,以便将 length_1 分配给 n=1 管道组件,并为所有其他管道组件分配 length_n:
parameter Integer n;
Modelica.Fluid.Pipes.DynamicPipe[n] pipe(
length=if n<2 then length_1 else cat(1,length_1,fill(length_n,n-1)));
上述框架中的一个简单模型如下所示:
model Test
parameter Integer n(min=1);
parameter Modelica.SIunits.Length length_1 = 0.1;
parameter Modelica.SIunits.Length length_n = 0.2;
Modelica.Fluid.Pipes.DynamicPipe[n] pipe(
redeclare each package Medium = Modelica.Media.Water.StandardWater,
each modelStructure=Modelica.Fluid.Types.ModelStructure.av_b,
each diameter=1,
length=if n==1 then length_1 else cat(1,length_1,fill(length_n,n-1)));
Modelica.Fluid.Sources.Boundary_pT boundary(
nPorts=1,
redeclare package Medium = Modelica.Media.Water.StandardWater,
p=100000,
T=293.15);
Modelica.Fluid.Sources.MassFlowSource_T boundary1(
nPorts=1,
redeclare package Medium = Modelica.Media.Water.StandardWater,
m_flow=1,
T=293.15);
inner Modelica.Fluid.System system(m_flow_start=1, T_start=293.15);
equation
if n == 1 then
connect(boundary1.ports[1], pipe[1].port_a);
connect(boundary.ports[1], pipe[1].port_b);
else
connect(boundary1.ports[1], pipe[1].port_a);
for i in 1:n-1 loop
connect(pipe[i].port_b, pipe[i+1].port_a);
end for;
connect(boundary.ports[1], pipe[n].port_b);
end if;
end Test;
就目前而言,该模型不起作用。我不确定 if 语句的构造方式是否有误,或者这是否根本不允许(如果我对 "each" 前缀的解释有误,可能就是这种情况)。
有什么想法吗?
首先感谢 matth 将我引向 Mike Tiller 书中的 pendulum example。
下面是修改代码以实现重复组件模式的两种可能方法,其中参数以某种预定方式更改。该错误与长度数组的定义方式有关。
选项#1:
已替换
length=if n==1 then length_1 else cat(1,length_1,fill(length_n,n-1))
和
length={if i==1 then length_1 else length_n for i in 1:n}
选项#2:
插入
final parameter Modelica.SIunits.Length[n]
lengths_pipe = {if i==1 then length_1 else length_n for i in 1:n};
并替换
... length=lengths_pipe
下面是使用第二个选项的完整工作代码:
model Test
parameter Integer n(min=1)=2;
parameter Modelica.SIunits.Length length_1 = 0.1;
parameter Modelica.SIunits.Length length_n = 0.2;
final parameter Modelica.SIunits.Length[n] lengths_pipe = {if i==1 then length_1 else length_n for i in 1:n};
Modelica.Fluid.Pipes.DynamicPipe[n] pipe(
redeclare each package Medium = Modelica.Media.Water.StandardWater,
each modelStructure=Modelica.Fluid.Types.ModelStructure.av_b,
each diameter=1,
length=lengths_pipe);
Modelica.Fluid.Sources.Boundary_pT boundary(
nPorts=1,
redeclare package Medium = Modelica.Media.Water.StandardWater,
p=100000,
T=293.15);
Modelica.Fluid.Sources.MassFlowSource_T boundary1(
nPorts=1,
redeclare package Medium = Modelica.Media.Water.StandardWater,
m_flow=1,
T=293.15);
inner Modelica.Fluid.System system(m_flow_start=1, T_start=293.15);
equation
if n == 1 then
connect(boundary1.ports[1], pipe[1].port_a);
connect(boundary.ports[1], pipe[1].port_b);
else
connect(boundary1.ports[1], pipe[1].port_a);
for i in 1:n-1 loop
connect(pipe[i].port_b, pipe[i+1].port_a);
end for;
connect(boundary.ports[1], pipe[n].port_b);
end if;
annotation (uses(Modelica(version="3.2.1")));
end Test;
想象有一个重复的组件模式(例如,动态管道),它有一个参数(例如,长度),该参数将根据它在模式中的位置而改变。我建议可以通过在感兴趣的参数之前省略 "each" 前缀来实现。
例如。让我们拿 n 个管道并按以下方式将它们添加到模型中:
parameter Integer n;
Modelica.Fluid.Pipes.DynamicPipe[n] pipe;
对于一个非常简单的示例,让我们指定我们希望模式中第一个管道的长度具有一定长度 (length_1),而所有其他管道具有 length_n。我的想法是,可以在按以下方式定义参数时放置一个 if 语句,以便将 length_1 分配给 n=1 管道组件,并为所有其他管道组件分配 length_n:
parameter Integer n;
Modelica.Fluid.Pipes.DynamicPipe[n] pipe(
length=if n<2 then length_1 else cat(1,length_1,fill(length_n,n-1)));
上述框架中的一个简单模型如下所示:
model Test
parameter Integer n(min=1);
parameter Modelica.SIunits.Length length_1 = 0.1;
parameter Modelica.SIunits.Length length_n = 0.2;
Modelica.Fluid.Pipes.DynamicPipe[n] pipe(
redeclare each package Medium = Modelica.Media.Water.StandardWater,
each modelStructure=Modelica.Fluid.Types.ModelStructure.av_b,
each diameter=1,
length=if n==1 then length_1 else cat(1,length_1,fill(length_n,n-1)));
Modelica.Fluid.Sources.Boundary_pT boundary(
nPorts=1,
redeclare package Medium = Modelica.Media.Water.StandardWater,
p=100000,
T=293.15);
Modelica.Fluid.Sources.MassFlowSource_T boundary1(
nPorts=1,
redeclare package Medium = Modelica.Media.Water.StandardWater,
m_flow=1,
T=293.15);
inner Modelica.Fluid.System system(m_flow_start=1, T_start=293.15);
equation
if n == 1 then
connect(boundary1.ports[1], pipe[1].port_a);
connect(boundary.ports[1], pipe[1].port_b);
else
connect(boundary1.ports[1], pipe[1].port_a);
for i in 1:n-1 loop
connect(pipe[i].port_b, pipe[i+1].port_a);
end for;
connect(boundary.ports[1], pipe[n].port_b);
end if;
end Test;
就目前而言,该模型不起作用。我不确定 if 语句的构造方式是否有误,或者这是否根本不允许(如果我对 "each" 前缀的解释有误,可能就是这种情况)。
有什么想法吗?
首先感谢 matth 将我引向 Mike Tiller 书中的 pendulum example。
下面是修改代码以实现重复组件模式的两种可能方法,其中参数以某种预定方式更改。该错误与长度数组的定义方式有关。
选项#1:
已替换
length=if n==1 then length_1 else cat(1,length_1,fill(length_n,n-1))
和
length={if i==1 then length_1 else length_n for i in 1:n}
选项#2:
插入
final parameter Modelica.SIunits.Length[n]
lengths_pipe = {if i==1 then length_1 else length_n for i in 1:n};
并替换
... length=lengths_pipe
下面是使用第二个选项的完整工作代码:
model Test
parameter Integer n(min=1)=2;
parameter Modelica.SIunits.Length length_1 = 0.1;
parameter Modelica.SIunits.Length length_n = 0.2;
final parameter Modelica.SIunits.Length[n] lengths_pipe = {if i==1 then length_1 else length_n for i in 1:n};
Modelica.Fluid.Pipes.DynamicPipe[n] pipe(
redeclare each package Medium = Modelica.Media.Water.StandardWater,
each modelStructure=Modelica.Fluid.Types.ModelStructure.av_b,
each diameter=1,
length=lengths_pipe);
Modelica.Fluid.Sources.Boundary_pT boundary(
nPorts=1,
redeclare package Medium = Modelica.Media.Water.StandardWater,
p=100000,
T=293.15);
Modelica.Fluid.Sources.MassFlowSource_T boundary1(
nPorts=1,
redeclare package Medium = Modelica.Media.Water.StandardWater,
m_flow=1,
T=293.15);
inner Modelica.Fluid.System system(m_flow_start=1, T_start=293.15);
equation
if n == 1 then
connect(boundary1.ports[1], pipe[1].port_a);
connect(boundary.ports[1], pipe[1].port_b);
else
connect(boundary1.ports[1], pipe[1].port_a);
for i in 1:n-1 loop
connect(pipe[i].port_b, pipe[i+1].port_a);
end for;
connect(boundary.ports[1], pipe[n].port_b);
end if;
annotation (uses(Modelica(version="3.2.1")));
end Test;