如何使用 Dymola 为特定变量设置收敛公差?

How to set a convergence tolerance to an specific variable using Dymola?

所以,我有一个带有压力损失的管道模型,其中未知量是质量流量。通常,在这个问题的大多数模型上,守恒方程用于计算质量流量,但是这样的模型有很多收敛问题(因为管末端的阻塞流导致无穷大的压力导数在结束)。请参见下图,左侧是问题的表示,右侧是显示无限压力导数的图表。

因此,我使用的是一个更稳健的模型,尽管它输出的不是质量流量而是管长,这是已知的。因此需要一个迭代循环来确定质量流量。好吧,我编写了一个函数 length,在给定管道几何形状、质量流量和边界条件的情况下,它输出计算出的管道长度,并使方程式如下:

    parameter Real L;
    Real m_flow;
...
equation
    L = length(geometry, boundary, m_flow)

它模拟得很好,但它需要很长时间......而且它不应该因为质量流量对管长度相当不敏感,例如。 if L=3 如果 length 的输出在 L ± 0.1 以内,我可以说 m_flow 已经收敛。另一方面,Dymola 中 DASSL 的默认收敛容差是 0.0001,这对所有其他变量都很好,但我的模型在这里是一个重大挫折...

话虽如此,我想知道是否有设置特定公差 L(来自 annotations 或其他)的(hacky)方法。我无法在网上或 Dymola 的用户手册中找到任何解决方案......到目前为止,我通过制作第二个函数来管理解决方法,该函数使用 Newton-Raphson 方法来确定质量流量,例如:

function massflowrate
    input geometry, boundary, m_flow_start, tolerance;
    output m_flow;
protected
    Real error, L, dL, dLdm_flow, Delta_m_flow;
algorithm
    error = geometry.L;
    m_flow = m_flow_start;
    while error>tolerance loop
        L = length(geometry, boundary, m_flow);
        error = abs(boundary.L - L);
        dL = length(geometry, boundary, m_flow*1.001);
        dLdm_flow = dL/(0.001*m_flow);
        Delta_m_flow = (geometry.L - L)/dLdm_flow;
        m_flow = m_flow + Delta_m_flow;
    end while;
end massflowrate;

然后我在方程式部分使用它:

    parameter Real L;
    Real m_flow;
...
equation
    m_flow = massflowrate(geometry, boundary, delay(m_flow,10), tolerance)

然而,这个解决方案并非没有问题,真正的方程是 非常 非线性的,并且取决于边界条件,求解器会达到一个永无止境的循环... =/

PS:对于冗长的 post 和缺少 MWE,我深表歉意,真正的方程式非常长,并且包含大量的热力学,我认为这没有任何帮助, 不过有需要的话我可以提供实物模型

长度函数是否平滑?对我来说,它不平滑似乎是问题的可能原因,@Phil 的建议也可能是个好主意。

不过,也应该可以按如下方式做你想做的事:

Real m_flow(nominal=1e9);

解释:方程通常求解到 unknowns 中的某个公差 - 在这种情况下 m_flow.

每个变量的公差是一个relative/absolute公差,考虑到标称值,Dymola不允许您为不同的变量设置不同的公差。

因此,计算 m_flow 不太准确的简单方法是为它设置一个较高的标称值,因为误差容限将是 tol*(abs(m_flow)+abs(nominal(m_flow))) 或类似的东西。

缺点是它可能太不准确,例如导致其他事件,或者错误是如此随机以至于求解器仍然变慢。