我目前正在尝试使用OpenModelica模拟声学共振器,并想知道如何稳健/优雅地计算它们的共振频率。
作为一个简化示例(不考虑介质等因素),我实现了一个双Helmholtz共振器,基本上是由两个容积(顺应度)通过一条管道(惯性)连接而成。真实系统由更多组件连接在一起。压力和体积流的振荡(均为复值)遵循正弦表达式,具有共振角频率w
。这会产生8个方程式,用于计算4个末端和4个顺应度-惯性连接点处的压力和体积流。
以下是我正在OpenModelica Nightly中解决的Modelica代码:
model Helmholtz_test "Simple test of double Helmholtz resonator"
constant Complex j = Modelica.ComplexMath.j;
ComplexU U_a, U_b, U_c, U_d "Oscillating volume flow rate";
ComplexPressure p_a, p_b, p_c, p_d "Oscillating pressure";
Modelica.SIunits.AngularFrequency w(start=2000, fixed=false);
Compliance C = 7.14e-9;
Inertance L = 80;
initial equation
p_a.re = 1e+2; //Simulation finishes, values reasonable, only during initialisation we get:
//Matrix singular!
//under-determined linear system not solvable!
//The initialization finished successfully without homotopy method.
equation
//BCs on ends
U_a = Complex(0);
U_d = Complex(0);
//Left compliance a-b;
p_a = p_b;
p_a = -1 / (j * w * C) * (U_b - U_a);
//Inertance b-c
U_b = U_c;
p_c - p_b = -j * w * L * U_b;
//Right compliance c-d
p_c = p_d;
p_c = -1 / (j * w * C) * (U_d - U_c);
//Additional condition for Eigenvalue
der(w) = 0;
//w^2 = 2/(L*C); //The "real" resonance frequency
annotation(
experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-06, Interval = 0.002));
end Helmholtz_test;
加入额外的定义
operator record ComplexPressure =
Complex(redeclare Modelica.SIunits.Pressure re,
redeclare Modelica.SIunits.Pressure im)
"Complex pressure";
operator record ComplexU =
Complex(redeclare Modelica.SIunits.VolumeFlowRate re,
redeclare Modelica.SIunits.VolumeFlowRate im)
"Complex volume flow rate";
type Compliance = Real(final quantity = "Compliance", final unit = "m3.Pa-1");
type Inertance = Real(final quantity="Inertance", final unit="kg.m-4");
在纸上计算后,我们可以得到一个共振角频率的公式w=\sqrt{\frac{2}{LC}}
(在这个例子中约为1871 1/s),以获得非零解。
为了避免求解器陷入无聊的零解,我必须在某个位置添加一些刺激,因此最初的方程式为p_a.re=1e+2
。
现在为了模拟这个情况,由于w
是一个额外的变量,我需要引入一个额外的方程,并选择der(w)=0;
,因为在这种情况下共振频率是恒定的。不幸的是,这使得不可能转向更复杂/更现实的情况,例如随温度或其他变化值而改变的共振频率。
Q1:有没有更好的方法来提供共振频率的额外方程/计算系统的特征值?
此外,仿真的成功取决于初始刺激的值(在某些范围内会失败,或者我在每个时间步骤中得到奇异方程)。事实上,在初始化阶段解决了这个问题。在最好的情况下,我可以得到输出:
Simulation finishes, values reasonable, only during initialisation we get:
Matrix singular!
under-determined linear system not solvable!
The initialization finished successfully without homotopy method.
Q2: 有没有办法避免奇异点和/或清洁地处理这种初始化(例如,使用homotopy
)?
虽然这在简化示例中可以正常工作(并且会产生正确的w
值),但我担心对于更复杂/现实模型,我可能会遇到更多问题的数值困难。
我已经研究了homotopy
,但我真的不知道如何在这里应用它。我想以某种方式将其应用于w
,但是Fritzson的书甚至似乎明确警告不要在导数表达式上使用它,并且除此之外似乎只有w.start
值存在。
equation
丢失了,你已经正确猜到了适当的位置。 - Christophw
是一个参数,而你所做的有点像参数识别,将其声明为参数应该是最好和最自然的方法。 - kabdelhak