在this question之后,我将代码修改为:
model test
// types
type Mass = Real(unit = "Kg", min = 0);
type Length = Real(unit = "m");
type Area = Real(unit = "m2", min = 0);
type Force = Real(unit = "Kg.m/s2");
type Pressure = Real(unit = "Kg/m/s2");
type Torque = Real(unit = "Kg.m2/s2");
type Velocity = Real(unit = "m/s");
type Time = Real(unit = "s");
// constants
constant Real pi = 2 * Modelica.Math.asin(1.0);
parameter Mass Mp = 0.01;
parameter Length r1 = 0.010;
parameter Length r3 = 0.004;
parameter Integer n = 3;
parameter Area A = 0.020 * 0.015;
parameter Time Stepping = 1.0;
parameter Real DutyCycle = 1.0;
parameter Pressure Pin = 500000;
parameter Real Js = 1;
//parameter Real Muk = 0.0;
parameter Real Muk = 0.158;
// variables
Length x[n];
Velocity vx[n];
Real theta;
Real vt;
Pressure P[n];
Force Fnsp[n];
Torque Tfsc;
initial equation
theta = 0;
vt = 0;
algorithm
for i in 1:n loop
if noEvent((i - 1) * Stepping < mod(time, n * Stepping)) and noEvent(mod(time, n * Stepping) < Stepping * ((i - 1) + DutyCycle)) then
P[i] := Pin;
else
P[i] := 0;
end if;
end for;
Tfsc := -r3 * Muk * sign(vt) * abs(sum(Fnsp));
equation
vx = der(x);
vt = der(theta);
x = r1 * {sin(theta + (i - 1) * 2 * pi / n) for i in 1:n};
Mp * der(vx) + P * A = Fnsp;
Js * der(theta) = Tfsc - r1 * Fnsp * {cos(theta + (i - 1) * 2 * pi / n) for i in 1:n};
// Js * der(theta) = - r1 * Fnsp * {cos(theta + (i - 1) * 2 * pi / n) for i in 1:n};
annotation(
experiment(StartTime = 0, StopTime = 30, Tolerance = 1e-06, Interval = 0.03),
__OpenModelica_simulationFlags(lv = "LOG_STATS", outputFormat = "mat", s = "dassl"));
end test;
但是,我收到的预处理警告
[1] ....翻译警告
撕裂的非线性方程组中具有默认零起始属性的迭代变量:
Fnsp[3]:VARIABLE(unit = "Kg.m/s2" ) type: Real [3] Fnsp[2]:VARIABLE(unit = "Kg.m/s2" ) type: Real [3] Fnsp[1]:VARIABLE(unit = "Kg.m/s2" ) type: Real [3] $DER.vt:VARIABLE() type: Real
这没有任何意义,但我认为我可以放心地忽略它,并且编译错误为:
矩阵单数!
欠定线性系统不可解
先前也曾报道here。如果我删除线
Torque Tfsc;
和
Tfsc := -r3 * Muk * sign(vt) * abs(sum(Fnsp));
并更改
Js * der(theta) = - r1 * Fnsp * {cos(theta + (i - 1) * 2 * pi / n) for i in 1:n};
完全正常。但是,将Muk
设置为零,这在理论上会导致与上述相同的错误!如果您能帮助我知道问题出在哪里以及如何解决,我将不胜感激。
P.S.1。在Dymola的演示版上,模拟测试无任何错误地结束,只有警告:
Some variables are iteration variables of the initialization problem:
but they are not given any explicit start values. Zero will be used.
Iteration variables:
der(theta, 2)
P[1]
P[2]
P[3]
P.S.2。使用JModelica,删除noEvent
并使用python代码:
model_name = 'test'
mo_file = 'test.mo'
from pymodelica import compile_fmu
from pyfmi import load_fmu
my_fmu = compile_fmu(model_name, mo_file)
myModel = load_fmu('test.fmu')
res = myModel.simulate(final_time=30)
theta = res['theta']
t = res['time']
import matplotlib.pyplot as plt
plt.plot(t, theta)
plt.show()
它为0.1
的小值(例如Muk
)快速地求解了模型。但是,它再次卡住以获得更大的价值。唯一的警告是:
Warning at line 30, column 3, in file 'test.mo':
Iteration variable "Fnsp[2]" is missing start value!
Warning at line 30, column 3, in file 'test.mo':
Iteration variable "Fnsp[3]" is missing start value!
Warning in flattened model:
Iteration variable "der(_der_theta)" is missing start value!
答案 0 :(得分:1)
您无需使用算法来分配方程式(即使它们位于for循环和if中)。我将它们移到方程部分,并完全删除了算法部分:
model test
// types
type Mass = Real(unit = "Kg", min = 0);
type Length = Real(unit = "m");
type Area = Real(unit = "m2", min = 0);
type Force = Real(unit = "Kg.m/s2");
type Pressure = Real(unit = "Kg/m/s2");
type Torque = Real(unit = "Kg.m2/s2");
type Velocity = Real(unit = "m/s");
type Time = Real(unit = "s");
// constants
constant Real pi = 2 * Modelica.Math.asin(1.0);
parameter Mass Mp = 0.01;
parameter Length r1 = 0.010;
parameter Length r3 = 0.004;
parameter Integer n = 3;
parameter Area A = 0.020 * 0.015;
parameter Time Stepping = 1.0;
parameter Real DutyCycle = 1.0;
parameter Pressure Pin = 500000;
parameter Real Js = 1;
//parameter Real Muk = 0.0;
parameter Real Muk = 0.158;
// variables
Length x[n];
Velocity vx[n];
Real theta;
Real vt;
Pressure P[n];
Force Fnsp[n];
Torque Tfsc;
initial equation
theta = 0;
vt = 0;
equation
for i in 1:n loop
if noEvent((i - 1) * Stepping < mod(time, n * Stepping)) and noEvent(mod(time, n * Stepping) < Stepping * ((i - 1) + DutyCycle)) then
P[i] = Pin;
else
P[i] = 0;
end if;
end for;
Tfsc = -r3 * Muk * sign(vt) * abs(sum(Fnsp));
vx = der(x);
vt = der(theta);
x = r1 * {sin(theta + (i - 1) * 2 * pi / n) for i in 1:n};
Mp * der(vx) + P * A = Fnsp;
Js * der(theta) = Tfsc - r1 * Fnsp * {cos(theta + (i - 1) * 2 * pi / n) for i in 1:n};
// Js * der(theta) = - r1 * Fnsp * {cos(theta + (i - 1) * 2 * pi / n) for i in 1:n};
end test;
这使编译器更容易找到强壮成分的合理排序和撕裂。这仍然会在19年代打破,但在此之前它可能正是您想要的。牛顿求解器在该阈值之后发散,因为我真的不知道您在这里做什么,所以很遗憾我无法提供对结果的任何分析。
答案 1 :(得分:1)
同样,由if方程触发的事件似乎可以由Sample
运算符完全替换。您可能想看看。