Loops Modelica:对静态解算器进行编程,以便在模拟过程中收敛到某个解。CFD实例

Loops Modelica:对静态解算器进行编程,以便在模拟过程中收敛到某个解。CFD实例,loops,static,modelica,fluid-dynamics,Loops,Static,Modelica,Fluid Dynamics,一般问题: 我使用OpenModelica在Modelica上工作。我想在Modelica中编程我自己的解算器,以收敛到一个解决方案,因为我认为OpenModelica无法解决我的问题。可能吗 具体情况: 我开发了流体动力学组件中空气分离的模型。我的模型基于一个数据表,该表提供了每个支管的压力损失系数,该系数取决于部件中的速度和参数“截面”。 当我使用质量流源时,我的模型运行良好,但当我仅使用压力源时,模型运行不好。请参见以下图片以了解与my component的连接: 我的“分离”模型的

一般问题:

我使用OpenModelica在Modelica上工作。我想在Modelica中编程我自己的解算器,以收敛到一个解决方案,因为我认为OpenModelica无法解决我的问题。可能吗


具体情况:

我开发了流体动力学组件中空气分离的模型。我的模型基于一个数据表,该表提供了每个支管的压力损失系数,该系数取决于部件中的速度和参数“截面”。 当我使用质量流源时,我的模型运行良好,但当我仅使用压力源时,模型运行不好。请参见以下图片以了解与my component的连接:

我的“分离”模型的代码如下:

model separation
 replaceable package Medium = Modelica.Media.Interfaces.PartialMedium "Medium in the component";
 Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium);
 Modelica.Fluid.Interfaces.FluidPort_b port_b2(redeclare package Medium = Medium);
 Modelica.Fluid.Interfaces.FluidPort_b port_b1(redeclare package Medium = Medium);
 Modelica.Blocks.Tables.CombiTable2D coeff_PDC1(table = [0, 0, 0.4, 0.5, 0.6, 0.7, 0.8, 1; 0, 1, 1, 1, 1, 1, 1, 1; 0.1, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81; 0.2, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64; 0.3, 0.5, 0.5, 0.52, 0.52, 0.5, 0.5, 0.5; 0.4, 0.36, 0.36, 0.4, 0.38, 0.37, 0.36, 0.36; 0.5, 0.25, 0.25, 0.3, 0.28, 0.26, 0.25, 0.25; 0.6, 0.16, 0.16, 0.23, 0.2, 0.18, 0.16, 0.16; 0.8, 0.04, 0.04, 0.16, 0.12, 0.07, 0.04, 0.04; 1, 0.001, 0.001, 0.2, 0.1, 0.05, 0.001, 0.001; 1.2, 0.07, 0.07, 0.36, 0.21, 0.14, 0.07, 0.07; 1.4, 0.39, 0.39, 0.78, 0.59, 0.49, 50, 50; 1.6, 0.9, 0.9, 1.36, 1.15, 50, 50, 50; 1.8, 1.78, 1.78, 2.43, 50, 50, 50, 50; 2, 3.2, 3.2, 4, 50, 50, 50, 50]);
 Modelica.Blocks.Tables.CombiTable1Ds coeff_PDC2( table = [0.1, 1; 0.2, 1; 0.3, 1; 0.4, 1; 0.5, 1; 0.6, 1; 0.8, 1; 1,1; 1.2, 1; 1.4, 1; 1.6, 1; 1.8, 1; 2, 1]);
 Real dp_b1 "en Pa, perte de charge entre les ports a1 et b";
 Real dp_b2 "en Pa, perte de charge entre les ports a2 et b";
 Modelica.SIunits.Velocity v_a(start = 0);
 Modelica.SIunits.Velocity v_b1(start = 0);
 Modelica.SIunits.Velocity v_b2(start = 0);
 parameter Real rho=1.2;
 parameter Modelica.SIunits.Area surface_b1 = 1;
 parameter Modelica.SIunits.Area surface_b2 = 1;
 parameter Modelica.SIunits.Area surface_a = 2;
equation 
 coeff_PDC1.u1 = if noEvent(abs(v_a) > 0) then v_b1/v_a else 1;
 coeff_PDC1.u2 = surface_b1/surface_a;
 coeff_PDC2.u = if noEvent(abs(v_a) > 0) then v_b2/v_a else 1;
 v_a = abs(port_a.m_flow)/rho/surface_a;
 v_b1 = abs(port_b1.m_flow)/rho/surface_b1;
 v_b2 = abs(port_b2.m_flow)/rho/surface_b2;
 port_b1.p - port_a.p = dp_b1;
 dp_b1 = 1/2*coeff_PDC1.y*port_b1.m_flow^2/surface_b1^2/rho;
 port_b2.p - port_a.p = dp_b2;
 dp_b2 = 1/2*coeff_PDC2.y[1]*port_b2.m_flow^2/surface_b2^2/rho;
 port_b1.m_flow + port_b2.m_flow + port_a.m_flow = 0;

 port_b1.Xi_outflow = inStream(port_a.Xi_outflow);
 port_b2.Xi_outflow = inStream(port_a.Xi_outflow);
 port_a.Xi_outflow = inStream(port_b1.Xi_outflow);
 port_b1.C_outflow = inStream(port_a.C_outflow);
 port_b2.C_outflow = inStream(port_a.C_outflow);
 port_a.C_outflow = inStream(port_b1.C_outflow);
 port_b1.h_outflow = inStream(port_a.h_outflow);
 port_b2.h_outflow = inStream(port_a.h_outflow);
 port_a.h_outflow = inStream(port_b1.h_outflow);
end separation;

当我将此模型连接到3个压力组件(源设置为Patm+10000Pa,汇设置为Patm)时,这是一个“非线性系统”错误。该模型与MassFlow水槽配合良好。为什么?我应该开发自己的解决方案来解决它吗?如果是,怎么做?

我不确定我是否100%理解这个问题。你说你不能用分析的方法来表达它。但是你能把
K
v
之间的关系表示成Modelica函数吗?如果是,则可以使用提供反函数。这样,该工具将使用最有效的函数版本,并且可以避免进行任何非线性迭代。但这是假设你可以建立反函数。根据您的解释,我不清楚您是否可以。OpenModelica暗示原始型号不好:

Error: Initialization problem is structurally singular, error found sorting equations 
  1: algorithm
    v := 0.0;
  2: algorithm
    K := 1.0;
    while v > 0.01 + $PRE.v loop
      v := (10.0 / K) ^ 0.5;
      K := 1.0 + v ^ 2.0;
    end while;
v在初始算法和算法部分都有定义。初始算法仅用于参数或状态(初始步骤中需要指定
der(x)
x
)。幸运的是,您可以指定
v(start=0)
,并且v将在分配给v的算法部分的开头初始化为0


解决该问题后,模型进行编译和模拟。尽管如其他人所说,算法部分很难看,在Modelica中应该不惜一切代价避免使用。

您的问题并不完全清楚。但是,我想你要问的是,如果给定一个dp值,在任何时候,当有一个K和v的关系表时,modelica能为v求解吗?如果我正确理解了您的变量,这应该可以做到:

model test5
  Real v "fluid velocity";
  Real K "Pressure loss coefficient";
  Real dp =0.5 "Pressure drop"; //Example value
  Real rho = 1.0 "density" ;
  Modelica.Blocks.Tables.CombiTable2D coeff_PDC1(table = [0, 0, 0.4, 0.5, 0.6, 0.7, 0.8, 1; 0, 1, 1, 1, 1, 1, 1, 1; 0.1, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81, 0.81; 0.2, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64; 0.3, 0.5, 0.5, 0.52, 0.52, 0.5, 0.5, 0.5; 0.4, 0.36, 0.36, 0.4, 0.38, 0.37, 0.36, 0.36; 0.5, 0.25, 0.25, 0.3, 0.28, 0.26, 0.25, 0.25; 0.6, 0.16, 0.16, 0.23, 0.2, 0.18, 0.16, 0.16; 0.8, 0.04, 0.04, 0.16, 0.12, 0.07, 0.04, 0.04; 1, 0, 0, 0.2, 0.1, 0.05, 0, 0; 1.2, 0.07, 0.07, 0.36, 0.21, 0.14, 0.07, 0.07; 1.4, 0.39, 0.39, 0.78, 0.59, 0.49, 50, 50; 1.6, 0.9, 0.9, 1.36, 1.15, 50, 50, 50; 1.8, 1.78, 1.78, 2.43, 50, 50, 50, 50; 2, 3.2, 3.2, 4, 50, 50, 50, 50]);
equation

  coeff_PDC1.u2 = 0.5;
  dp = 0.5 * K * rho * v ^ 2;
  v = coeff_PDC1.u1;
  K = coeff_PDC1.y;

end test5;

当我运行这个程序时,它会解出v,给定一个dp值。这就是你想要的吗?

你应该使用
等式
部分,而不是
算法
部分。然后解算器(Dymola、OpenModelica,无论您使用什么)将为您反转方程(如果可能,从分析角度,否则从数值角度)。在我的真实模型中,解析方程是不可能的,OpenModelica也不能成功地收敛于数值可战斗性。所以我想尝试另一种解决方案,但我想你回答我“我不能为自己的解算器编程”。谢谢。是的,就是这样。我想简化我的问题,把重点放在这个问题上,但我错过了我的模型功能失调的真正原因(因为我最终不知道是哪一个)。我将在问题中添加我的模型的所有代码。