如何避免Modelica中的过度确定系统?

如何避免Modelica中的过度确定系统?,modelica,dymola,openmodelica,Modelica,Dymola,Openmodelica,我目前正在OpenModelica中基于Modelica.Fluid.Pipes.StaticPipe创建一个管道。我创建的模型非常相似,但我尝试实现特征方法 当我检查模型时,它计算了38个方程和10个变量,因此系统是超定的。据我所知,我需要我编写的每一个等式,因此我认为变量和常量的声明是错误的 我通常是这样声明变量和常量的: 定义我希望用户更改的内容时(在OpenModelica的GUI中),我使用参数,例如参数SIunits.Length=1 定义我不希望用户更改的内容时,我使用最终参数,例

我目前正在OpenModelica中基于Modelica.Fluid.Pipes.StaticPipe创建一个管道。我创建的模型非常相似,但我尝试实现特征方法

当我检查模型时,它计算了38个方程和10个变量,因此系统是超定的。据我所知,我需要我编写的每一个等式,因此我认为变量和常量的声明是错误的

我通常是这样声明变量和常量的:

  • 定义我希望用户更改的内容时(在OpenModelica的GUI中),我使用
    参数
    ,例如
    参数SIunits.Length=1
  • 定义我不希望用户更改的内容时,我使用
    最终参数
    ,例如
    最终参数SIunits.Area crossArea=Modelica.Constants.pi*diameter*diameter/4
  • 当声明我需要在
    方程中使用的东西时
    我只使用正确的类型,例如
    实f“Darcy Weisbach摩擦系数”。我通常有单独的函数,这些函数稍后存储在
    方程中的这些变量中
  • 当声明在
    方程中使用的数组时
    我使用
    最终参数
    ,例如
    最终参数实f_数组[j_长度,I_长度]
  • 在方程中,当在数组中存储变量时,我这样做:
    f_数组[j,I]=函数。摩擦力(v=v,D=直径,rho=rho,mu=mu,eps=粗糙度)
  • 下面是我的代码的简化片段。为了便于阅读,我省略了一些声明

        model pipe_MSL
           outer Modelica.Fluid.System system;
           extends Modelica.Fluid.Interfaces.PartialTwoPort;
    
           // Geometry
           parameter SI.Length length=1 "Length";
           final parameter SI.Area crossArea=Modelica.Constants.pi*diameter*diameter/4;
    
           // Initialization
           final parameter Medium.AbsolutePressure p_a_start=system.p_start;
    
           // Method of Characteristics declarations
           Real f "Darcy-Weisbach friction factor";
           Real B "Impedance from MOC";
           Real R "Resistance from MOC";
           final parameter Real dx = length/3
           final parameter Integer N = integer(length/dx)
           final parameter Real dt = dx/a "Time step";
           Real v "Water velocity";
    
           // Local array storage declarations.
           final parameter Real B_array[T,N];
        
        initial equation
           //Initial condition
           B_array[1,:] = {Functions.B_Impedance(a=a, A=crossArea, g=system.g)*k for k in 1:N};
    
        equation
           for j in 1:T loop
              //Left boundary condition
              Cm_array[j+1,1] = OpenWPL.Functions.C_minus(Hb=H_array[j,2], B=Bm_array[j,1], Qb=Q_array[j,2]);
    
              for i in 1:(N-1) loop
                 B_array[j,i] = Functions.B_Impedance(a=a, A=crossArea, g=system.g) + R_array[j,i]*abs(Q_array[j,i-1]);;
              end for; 
           end for;
        end pipe_MSL;
    
    我的问题是:

  • 我是否正确使用了
    参数/final参数/Real
    和其他声明?我已经一遍又一遍地阅读了迈克尔·蒂勒关于变量的指南,但我不知道我是否正确使用了它们
  • 关于如何使系统不过度确定,有什么具体的提示吗
  • 当模拟时(即使系统是过度确定的),我得到了错误
    内部错误Cm_数组[2,1]=OpenWPL.Functions.C_减号(H_数组[1,2],Bm_数组[1,1],Q_数组[1,2])的大小为1,但变量为0()
    。你知道怎么解决这个问题吗

  • 如果需要,我可以发布代码的完整版本。提前感谢。

    您没有正确使用参数,还有一个错误:

    • 您可以使用
      fixed=false
      为参数建立初始方程,但是
      B_array
      似乎不是一个参数,因为它有一个正常的方程。因此,删除
      B_数组前面的参数
    • B_数组
      的初始方程将不起作用(见下文);删除它以开始
    • 或者,您必须编写
      B_数组(每个固定=false)
      ,并确保
      B_数组的所有元素都有初始方程,而不仅仅是一行
    • 您有一些变量(目前)未被使用—只需删除它们的声明:
      f、B、R、v
      (除非您没有给出方程式)
    初始方程仅用于确定状态(有时是参数);其思想是变量必须满足正规方程和初始方程。因此,有一个看起来像正常方程的初始方程是行不通的

    新增:如果目标是编写自己的时间离散方程组,而不使用Modelica求解微分方程,我看到两种可能性:

    • 将其转换为函数中的传统算法,这样您就有了
      参数Real B_array[T,N]=MyDiscredition(…)和函数MyDiscredition中的所有内容
    • 或者把一切都当作方程式<代码>主模型中的实B_数组[T,N]
    工具应该能够看到方程是参数化的,并且只需求解一次

    在这两种情况下,您都必须非常小心索引:

    • 上面是
      i in 1:(N-1)
      但是使用
      Q_数组[j,i-1]
    • 初始条件适用于
      B_数组[1,:]
      ,但
      B_数组[1,:]
      也有正常方程

    那么初始方程应该是
    B_数组[:,1]
    的,而不是
    i在2:N
    中的循环,因为这确保了所有元素都有一个方程?还是更微妙?

    在我看来,你是在把变量和参数混合在一起。参数在整个模拟过程中都是收缩的。因此,数组应声明为变量,即删除最终参数最后一个错误是因为参数只有初始方程,不应在正则方程中求解。Final用于不变的事物——变量、参数或常量。我建议对数组维度使用常量。用户还可以在GUI中更改变量和常量,如果您给他们一个对话框注释,您可以控制它们显示的位置。@AtiyahElsheikh谢谢。声明数组时删除最后一个参数解决了我的一系列问题。然而,当我试图从
    最终参数Real dx=length/3
    中删除
    最终参数时(在整个模拟过程中都是常量),我得到的错误
    维度必须是参数或常量表达式(N)。
    Real fp_数组[T,N]中。您知道如何解决这个问题吗?@sjoelund.se在删除
    最终参数后
    上一个错误消失了,如您所述。我还声明了另一个边界条件(我在我的原始帖子中遗漏了),即
    H_数组[j+1,1]=1internalerrorpipe.H_array[3,1]=1.0的大小为1,但是0个变量()
    )现在出现在这里。你也知道如何解决这个问题吗?谢谢你的回复@Jonas d_x是一个参数,所以您可以将它声明为一个参数