如何找到振荡器的谐振频率?

时间:2019-09-03 07:54:09

标签: modelica openmodelica acoustics

我目前正在尝试使用OpenModelica模拟声谐振器,我想知道如何稳健/精确地计算其谐振频率。

作为一个简化的示例(没有Media等),我实现了一个双亥姆霍兹共振器,实质上是通过管道(惯性)连接的两个体积(合规)。实际的系统由连接在一起的更多组件组成。 压力和体积流量(均为复数值)的振荡遵循正弦表达式,并具有共振角频率w。对于4个压力和4个体积流量(在端点和依从度-惯性连接点),这产生了8个方程。

这是我每晚在OpenModelica中解决的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; ,因为在此谐振频率是恒定的案件。 不幸的是,这使得不可能进入更复杂/更现实的情况,在该情况下谐振频率随时间变化,例如,谐振频率随时间变化。温度或其他变化值。

问题1:是否有更好的方法为共振频率提供附加方程式/计算系统的本征值?

此外,模拟的成功取决于初始刺激的值(在某些范围内,此操作将失败或在每个时间步长上我都得到奇异的方程式)。同样,实际上,该问题在初始化阶段已得到解决。在最好的情况下,我得到了输出

Simulation finishes, values reasonable, only during initialisation we get:
Matrix singular!
under-determined linear system not solvable!
The initialization finished successfully without homotopy method.

问题2:是否有办法避免奇异和/或干净地处理此初始化(例如,使用homotopy)? 尽管在简化的示例中这可以正常工作(并为w产生正确的值),但我担心对于更复杂/现实的模型,我可能会遇到更多有问题的数字难题。 我已经研究了homotopy,但是我真的看不到如何在这里应用它。我本以为以某种方式将其应用于w,但弗里兹森(Fritzson)书甚至似乎明确警告不要在派生表达式上使用此值,此外,似乎只有w.start值本身存在。

2 个答案:

答案 0 :(得分:1)

ComplexUComplexPressureComplianceInertance是什么类?我尝试运行您的模型,但是这些似乎是您正在使用的另一个库的一部分。我用MSL或原始类型替换了它们。

此外,我还不太了解该模型的工作原理,您只定义了一个initial equation块,而没有实际的方程式。我尝试了以下模型:

model Helmholtz_test "Simple test of double Helmholtz resonator"
  constant Complex j = Modelica.ComplexMath.j;
  Complex U_a, U_b, U_c, U_d "Oscillating volume flow rate";
  Complex p_a, p_b, p_c, p_d "Oscillating pressure";
  parameter Modelica.SIunits.AngularFrequency w(start=2000, fixed=false);
  Modelica.SIunits.AngularFrequency real_w; //The "real" resonance frequency
  Real C = 7.14e-9;
  Real L = 80;
initial equation
  p_a.re = 1e+2;
equation
  U_a = Complex(0);
  U_d = Complex(0);
  p_a = p_b;
  p_a = -1 / (j * w * C) * (U_b - U_a);
  U_b = U_c;
  p_c - p_b = -j * w * L * U_b;
  p_c = p_d;
  p_c = -1 / (j * w * C) * (U_d - U_c);
  real_w = abs(sqrt(2/(L*C))); //The "real" resonance frequency
end Helmholtz_test;

我这就是你想要的吗?

您可以将wreal_w进行比较。一种是通过求解系统来计算的,另一种是通过方程式计算的。

如您所见,标准求解器很费力,但是总的枢轴求解器却可以解决系统问题。它收敛到另一端(p_d.re = -1e+2;),所以也许这是正确的值吗?

编辑: 我将模型更改为正确的模型,我用最初的方程式弄乱了,现在一切正常!主求解器仍然失败,但是总枢轴找到了解决方案。

答案 1 :(得分:0)

我想补充一下有关失效的非线性求解器的另一件事! 如果您正在使用最新的每晚版本,则应收到以下消息:

Nonlinear iteration variables with default zero start attribute in NLSJac8. (1)
========================================
1: U_b.im:VARIABLE()  "Imaginary part of complex number" type: Real 
Nonlinear iteration variables with predefined start attribute in NLSJac8. (1)
========================================
1: w:VARIABLE(start = 2000.0 unit = "rad/s" fixed = false )  type: Real Info: Only non-linear iteration variables in non-linear eqation systems require start values. All other start values have no influence on convergence and are ignored. Use "-d=dumpLoops" to show all loops. In OMEdit Tools->Options->Simulation->OMCFlags, in OMNotebook call setCommandLineOptions("-d=dumpLoops") 

此处报告的每个变量都应有一个起始值,如您所见w已经有一个起始值,但是U_b的虚部缺少一个。声明时,可以将其更改为U_b(im(start=10))。尽管您知道结果会很小,但是必须避免很大以免出现奇异之处。