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

时间:2018-07-10 15:17:27

标签: solver modelica

所以,我有一个压力损失管的模型,其中未知的是质量流速。通常,在该问题的大多数模型上,均采用守恒方程来计算质量流量,但此类模型存在许多收敛问题(因为管端的阻塞流量会导致在管道末端产生无限大的压力导数)。结束)。参见下图,该问题在左侧和右侧以图表形式显示了无限压力导数。

Problem representation

因此,我使用的模型更健壮,尽管它不输出质量流率,但输出管长,这是已知的。因此,需要一个迭代循环来确定质量流率。好的,然后,我对函数length进行了编码,该函数给出了管的几何形状,质量流量和边界条件,它输出计算出的管长度,并使方程式如下:

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

它模拟的很好,但是要花一些时间……而且不应该这样,因为质量流率对管子的长度不敏感,例如如果L=3可以说m_flow已经收敛,如果长度的输出在L ± 0.1之内。另一方面,Dymola中DASSL的默认收敛容限为0.0001,这对所有其他变量都适用,但是在这里我的模型遇到了重大挫折...

话虽这么说,我想知道是否有一种(特别的)方法来设置特定的容忍度L(来自annotations或其他方式)。我无法在线找到任何解决方案,也无法在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:很抱歉,我的工作很长,而且缺少MWE,所以实际方程很长,而且负载了热力学,我认为这对我们没有任何帮助,因为如果需要的话,我能够提供真实的模型。

1 个答案:

答案 0 :(得分:2)

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

但是,也应该可以按照以下方式做您想做的事情:

Real m_flow(nominal=1e9);

说明:方程式通常在未知数中求解为一定的公差-在这种情况下为m_flow。

每个变量的容差是考虑到标称值的相对/绝对容差,而Dymola不允许您为不同的变量设置不同的容差。

因此,不那么准确地计算m_flow的简单方法是为其设置较高的标称值,因为容错度将为tol*(abs(m_flow)+abs(nominal(m_flow)))或类似的值。

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