如何从算法部分提取值?

时间:2013-02-24 09:05:33

标签: modelica openmodelica

我正在使用抛物线PDE与代数方程混合加上所有这些方程耦合。 我在OM(1.9.1)(“residualFcn [some number]”)中使用Euler方法(Dassl太慢)和大容差(用于快速模拟)和recive错误(两种类型)。问题是求解器可以'解决非线性系统(数学上,系统是正确的)。 第一个问题是什么类型的方法在OM中使用Euler积分方法(显式或隐式或Crank-Nicholson ......或......)? 所以我试图用数字解决它(显式欧拉方法(在下面的代码“new [N]”)(也许问题可能是CFL条件。),但我有问题(特定样本时间的样本重建)。 那么,第二个问题是指再生特定样本时间的值?! 在下面的代码中有数组“a [3]”。 想法是针对每个“ts(采样时间)”重建3个节点中的值。 如何才能做到这一点? 如何从算法部分的当前值(即节点)传递到方程部分? 我在.txt文件中有所有值,我使用Matlab绘制它们,但我不知道如何传递它,即在“方程式”部分或其他方式。 同样的问题是“new [N]”,对于特定的采样时间,节点的绘图函数(N)。

还有一件事,如果delta(t)/(delta(x))^ 2> = 0.5(delta(t)定义用户,并且参考等式部分,delta(x)如下面的代码所示,空间离散化用于方程部分(经典前馈法)),数值稳定性是否满足? 同样的例子,但算法部分? 此致

这是代码:

model Euler1D
import Modelica.Utilities.*;
parameter Integer N=10; //50
parameter Real Lp=1e-6;
parameter Real deltax=1/(N-1)*Lp;
Real a[3];
Real old[N];
Real new[N];
Real b;
equation 
a[1]=if 
   (time>5) then 0 else time+5;
a[2]=time;
a[3]=2;
when 
(sample(0,1)) then
d=b;
end when;
algorithm 
// IN t=ts;
 when (sample(0,1)) then
 for i in 1:2 loop
  b:=a[i];
 Streams.print(String(time)+"   "+String(a[i])+ "     "+String(b), "C:/Some_Path/text.txt");
end for;
end when;

// Another problem
old[1]:=10;
old [N]:=0;
new[1]:=10;
new [N]:=0;
// Boundary
for i in 2:N-1 loop
old [i]:=10;
new[i]:=10;
end for;

for dx in deltax:deltax:Lp-deltax loop  // spatial discretization

for i in 2:N-1 loop
(new[i]):=(old[i]+0.5*(old[i + 1] +old[i-1]- 2*old[i]));
//def:=def+abs(new[i]-old[i]);
end for;
 for i in 2:N-1 loop
 old[i]:=new[i]; // switch the values
 end for;

 for i in 1:N loop
 Streams.print(String(time)+"   "+ String(new[2]), "C:/Some_Path/Anel_Nodes.txt");
 end for;

 annotation (uses(Modelica(version="3.2")));
 end Euler1D;

1 个答案:

答案 0 :(得分:2)

鉴于您的意见,我将如何构建模型:

model Euler1D 
  parameter Integer N=10 "Spatial discretization";
  parameter Modelica.SIunits.Length L=1;
protected 
  parameter Modelica.SIunits.Length dx=L/(N-1) "Segment size";
  Real c[N] "Solution variable c";
  Real J[N] "Solution variable J";
  Real dc_dx "Spatial derivative at x==L";
  Real d2c_dx2[N] "Second spatial derivative of c";
initial equation 
  der(c[2:N-1]) = zeros(N-2);
equation 
  // Equations for spatial derivatives
  d2c_dx2[2:N-1] = { (c[i+1]-2*c[i]+c[i-1])/(dx^2) for i in 2:N-1};
  dc_dx = (c[N]-c[N-1])/dx;

  // Boundary conditions
  c[1] = 0 "Dirichlet B.C.";
  dc_dx = 1 "Neumann B.C.";

  // PDE
  J = c .* c "J = c^2";
  der(c) = d2c_dx2+J "PDE";
end Euler1D;

初始方程避免了模拟开始时的大瞬态。如此有效,我提出的模型将为您提供稳定的状态解决方案。但是你可以把时间变化(例如边界条件)。

在这方面可能仍然存在一些错误,但我很难说,因为我对这个系统没有多少直觉,而且无论如何我都不知道我使用过的值是否具有实际意义

但希望它概述了如何构建这样的模型。这个模型在Dymola运行。我没有在OpenModelica中尝试过它。

所有这一切,你总是在PDE中解决这个问题,即时间积分方案无法明确看到的物理学中存在隐含的约束(例如CFL条件)。通常,可变时间步长算法具有误差估计,并且它们可以间接地看到由于违反这些隐式约束而引入的不稳定性。但他们必须通过他们“摸索”。我不确定这将成为上述模型的问题的程度。

如果您想为解决方案添加一点兴奋,可以更改等式

  dc_dx = 1 "Neumann B.C.";

...到...

  dc_dx = 0.7+0.2*sin(time) "Neumann B.C.";

...你会得到一个很好的时间变化的解决方案。我注意到,当玩这个时,如果你让渐变结果太陡,模型会变得不稳定。无论这是由于我上面提到的问题导致的基础数学方程式的真正解决方案还是数值假象,我都不知道。因此,如果您想要一个稳定的解决方案,那么您可以在此模型中加入限制。