Modelica(Dymola)中一维热扩散PDE的实现
我试图实现Peter Fritzon的“Modelica 3.3面向对象建模与仿真”中的一维热扩散示例,该示例基于一维热扩散的网格函数有限差分方法,但我得到了一个错误:Modelica(Dymola)中一维热扩散PDE的实现,modelica,pde,dymola,Modelica,Pde,Dymola,我试图实现Peter Fritzon的“Modelica 3.3面向对象建模与仿真”中的一维热扩散示例,该示例基于一维热扩散的网格函数有限差分方法,但我得到了一个错误: Translation of Heat_diffusion_Test_1D.HeatDiffusion1D: The DAE has 50 scalar unknowns and 50 scalar equations. Cannot find differentiation function: Heat_diffusion
Translation of Heat_diffusion_Test_1D.HeatDiffusion1D:
The DAE has 50 scalar unknowns and 50 scalar equations.
Cannot find differentiation function:
Heat_diffusion_Test_1D.DifferentialOperators1D.pder(
u,
1)
with respect to time
Failed to differentiate the equation
Heat_diffusion_Test_1D.FieldDomainOperators1D.right(Heat_diffusion_Test_1D.DifferentialOperators1D.pder (
u,
1)) = 0;
in order to reduce the DAE index.
Failed to reduce the DAE index.
Translation aborted.
ERROR: 1 error was found
WARNING: 1 warning was issued
我是编程语言的新用户,你知道我如何解决这个问题吗?显然,问题在于右边界的边界条件。
提前谢谢你
代码如下:
package Heat_diffusion_Test_1D
import SI = Modelica.SIunits;
model HeatDiffusion1D
import SI = Modelica.SIunits;
parameter SI.Length L=1;
import Heat_diffusion_Test_1D.Fields.*;
import Heat_diffusion_Test_1D.Domains.*;
import Heat_diffusion_Test_1D.FieldDomainOperators1D.*;
import Heat_diffusion_Test_1D.DifferentialOperators1D.*;
constant Real PI=Modelica.Constants.pi;
Domain1D rod(left=0, right=L, n=50);
Field1D u(domain=rod, redeclare type FieldValueType=SI.Temperature, start={20*sin(PI/2*x)+ 300 for x in rod.x});
equation
interior(der(u.val))=interior(4*pder(u,x=2));
left(u.val)=20*sin(PI/12*time)+300;
right(pder(u,x=1)) = 0;
//right(u.val)=320;
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end HeatDiffusion1D;
package Fields
record Field1D "Field over a 1D spatial domain"
replaceable type FieldValueType = Real;
parameter Domains.Domain1D domain;
parameter FieldValueType start[domain.n]=zeros(domain.n);
FieldValueType val[domain.n](start=start);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end Field1D;
annotation ();
end Fields;
package Domains
import SI = Modelica.SIunits;
record Domain1D "1D spatial domain"
parameter SI.Length left=0.0;
parameter SI.Length right=1.0;
parameter Integer n=100;
parameter SI.Length dx = (right-left)/(n-1);
parameter SI.Length x[n]=linspace(right,left,n);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end Domain1D;
annotation ();
end Domains;
package FieldDomainOperators1D
"Selection operators of field on 1D domain"
function left "Returns the left value of the field vector v1"
input Real[:] v1;
output Real v2;
algorithm
v2 := v1[1];
end left;
function right "Returns the left value of the field vector v1"
input Real[:] v1;
output Real v2;
algorithm
v2 := v1[end];
end right;
function interior
"returns the interior values of the field as a vector"
input Real v1[:];
output Real v2[size(v1,1)-2];
algorithm
v2:= v1[2:end-1];
end interior;
end FieldDomainOperators1D;
package DifferentialOperators1D
"Finite difference differential operators"
function pder
"returns vector of spatial derivative values of a 1D field"
input Heat_diffusion_Test_1D.Fields.Field1D f;
input Integer x=1 "Diff order - first or second order derivative";
output Real df[size(f.val,1)];
algorithm
df:= if x == 1 then SecondOrder.diff1(f.val, f.domain.dx)
else
SecondOrder.diff2(f.val, f.domain.dx);
end pder;
package SecondOrder
"Second order polynomial derivative approximations"
function diff1 "First derivative"
input Real u[:];
input Real dx;
output Real du[size(u,1)];
algorithm
du := cat( 1, {(-3*u[1] + 4*u[2] - u[3])/2/dx}, (u[3:end] - u[1:end-2])/2/dx, {(3*u[end] -4*u[end-1] + u[end-2])/2/dx});
end diff1;
function diff2
input Real u[:];
input Real dx;
output Real du2[size(u,1)];
algorithm
du2 :=cat( 1, {(2*u[1] - 5*u[2] + 4*u[3]- u[4])/dx/dx}, (u[3:end] - 2*u[2:end-1] + u[1:end-2])/dx/dx, {(2*u[end] -5*u[end-1] + 4*u[end-2] - u[end-3])/dx/dx});
end diff2;
annotation ();
end SecondOrder;
package FirstOrder
"First order polynomial derivative approximations"
function diff1 "First derivative"
input Real u[:];
input Real dx;
output Real du[size(u,1)];
algorithm
// Left, central and right differences
du := cat(1, {(u[2] - u[1])/dx}, (u[3:end]-u[1:end-2])/2/dx, {(u[end] - u[end-1])/dx});
end diff1;
annotation ();
end FirstOrder;
annotation ();
end DifferentialOperators1D;
annotation (uses(Modelica(version="3.2.1")));
end Heat_diffusion_Test_1D;
如果您使用
注释(inline=true)
在包FieldDomainOperators1D
和DifferenticationOperators1d
中的所有函数,您的实现将在Dymola 2015 FD01
中进行翻译和模拟。原因由Peter Fritzson在第406页给出:
[…]注意,pder()
函数和
网格函数。[…]这使我们有可能向这样一家公司打电话
在通常不允许函数调用的地方使用函数。[……]
我不确定当前版本的modelica标准库中是否定义了
pder
运算符,我也不认为本书所指的3.3库已经发布?@Christoph如果当前版本中没有定义pder,那是对的。我将其定义为代码中的函数。Modelica标准库是3.2.1。Modelica语言规范是3.3,已经在Dymola(2016 FD01)中实现。我不确定我是否正确理解了这个答案。我想知道你是否可以如此幼稚地在你的帖子中添加正确版本的代码?