LoginSignup
1
0

More than 3 years have passed since last update.

動吸振器の問題を解く(後編)

Last updated at Posted at 2020-12-23

動吸振器の問題を解く(1)の続き

前回はルンゲ=クッタ法で2自由度の2階の微分方程式(連成振動)の数値計算が行えるところまで確かめた。
今回は、周波数特性のグラフ化まで行う。
主系に対する従系の質量比、ダンパ減衰比、バネ剛性比を変えた状態で周波数特性を比較することで、目的に応じた動吸振器の設計が可能になるだろう。

ループの打ち切り

       %% Store extreme values
            if i>2 && ym(i,j,iRk)<ym(i-1,j,iRk) && ym(i-1,j,iRk)>ym(i-2,j,iRk)
                yex(s,j,iRk)=ym(i-1,j,iRk);
                s=s+1;
            end

            %% Check the decrese of extreme values 
            if s>10 && yex(s-1,j,iRk)<(yex(s-2,j,iRk)+yex(s-3,j,iRk)+yex(s-4,j,iRk)+yex(s-5,j,iRk))/4.8
                fin(j,iRk)=s;
                break
            else 
            [ym(i+1,j,iRm,iRc,iRk),ya(i+1,j,iRm,iRc,iRk),vm(i+1,j,iRm,iRc,iRk),va(i+1,j,iRm,iRc,iRk)] ...
            = RungeKutta(ym(i,j,iRm,iRc,iRk),ya(i,j,iRm,iRc,iRk),vm(i,j,iRm,iRc,iRk),va(i,j,iRm,iRc,iRk),Rm(iRm),Rc(iRc),Rk(iRk),Rs(j),zm,dtau*i,dtau);
            end

一番下のサンプルコードの、この部分でループの打ち切り判定を行う
おおまかな意味は

①極大値格納
②if 極大値が(手前4つの極大値の和/4.8)より小さい
 →減衰しているのでループ打ち切り(打ち切り点を記録)
 else 計算続行

である。
この部分を時間ループ、周波数ループ、パラメータ比のループ(Rm,Rc,Rk)の5つの入れ子でループさせる。
打ち切りなし
3.jpg

打ち切りあり
4.jpg

これでかなり計算量が減るので計算時間が格段に減った。

パラメータ比ごとの計算

パラメータ比の宣言がこちらである。

Rm = 1;
Rc = 1;
Rk = [0.1,1,10];

ベクトルになっているので、好きに値を変更・追加できる。

パラメータ比ごとに計算させるために、変位、速度の変数が

ym = zeros(Tn+1,Fn,RmN,RcN,RkN);
ya = zeros(Tn+1,Fn,RmN,RcN,RkN);
vm = zeros(Tn+1,Fn,RmN,RcN,RkN);
va = zeros(Tn+1,Fn,RmN,RcN,RkN);

このような形の5次元配列になっている。
各要素ごとにforループを増やせば良いというわけだ。

計算数はTn,Fnで宣言している。ここを増やすことで時間、および周波数の計算数が増加し、精度の高い結果が得られる。

周波数特性

各周波数ごとに変位の最大値を格納していき、周波数に対応させてプロットさせる。
ここの計算で、無次元化した変位をもとの変位に戻している。($y = x/(F/k_m)$より)

xm(j,iRm,iRc,iRk) = F/km*max(ym(:,j,iRm,iRc,iRk));
xa(j,iRm,iRc,iRk) = F/km*max(ya(:,j,iRm,iRc,iRk));

周波数は$f = R_s/T_m$ なので、それに対応させたプロットをすれば、無次元化ではなくもとの微分方程式の値が算出される。

サンプルコード

clear
close
hold off

%% Input
RsLow =0; %"1" is Out of Phase , "0" show both
RsHigh =5; % Freq end

Tn = 5000;
Fn = 500;

Rm = [1];
Rc = [1.2];
Rk = [0.1,1,10];

mm = 10;
cm = 0.001;
km = 30;
F = 1; % Force

zm = cm / (2*sqrt(mm*km));
sm = sqrt(km/mm);
Tm = 2*pi/ sm; % Period


%% Loop preparation

% Declaration
ym = zeros(Tn+1,Fn,RmN,RcN,RkN);
ya = zeros(Tn+1,Fn,RmN,RcN,RkN);
vm = zeros(Tn+1,Fn,RmN,RcN,RkN);
va = zeros(Tn+1,Fn,RmN,RcN,RkN);


% Loop variable
RmN = length(Rm);
RcN = length(Rc);
RkN = length(Rk);
dtau = 0.1 *sm;
Rs = RsLow:(RsHigh-RsLow)/Fn:RsHigh;

% For plot
freq = Rs/Tm;
N_freq = sm/(2*pi);

% max variable
xm=zeros(Fn+1,RmN,RcN,RkN);
xa=zeros(Fn+1,RmN,RcN,RkN);

% Loop cutoff variable
yex= zeros(Tn,Fn,RmN,RcN,RkN);
maxI = 0;
fin=zeros(Fn,RmN,RcN,RkN);

%% Calculation
for iRm = 1:RmN
for iRc = 1:RcN
for iRk = 1:RkN
    for j=1:Fn % frequency loop
        s=1;
        for i=1:Tn % time loop
            %% Store extreme values
            if i>2 && ym(i,j,iRk)<ym(i-1,j,iRk) && ym(i-1,j,iRk)>ym(i-2,j,iRk)
                yex(s,j,iRk)=ym(i-1,j,iRk);
                s=s+1;
            end
            %% Check the decrese of extreme values 
            if s>10 && yex(s-1,j,iRk)<(yex(s-2,j,iRk)+yex(s-3,j,iRk)+yex(s-4,j,iRk)+yex(s-5,j,iRk))/4.8
                fin(j,iRk)=s;
                break
            else 
            [ym(i+1,j,iRm,iRc,iRk),ya(i+1,j,iRm,iRc,iRk),vm(i+1,j,iRm,iRc,iRk),va(i+1,j,iRm,iRc,iRk)] ...
            = RungeKutta(ym(i,j,iRm,iRc,iRk),ya(i,j,iRm,iRc,iRk),vm(i,j,iRm,iRc,iRk),va(i,j,iRm,iRc,iRk),Rm(iRm),Rc(iRc),Rk(iRk),Rs(j),zm,dtau*i,dtau);
            end
        end
        xm(j,iRm,iRc,iRk) = F/km*max(ym(:,j,iRm,iRc,iRk));
        xa(j,iRm,iRc,iRk) = F/km*max(ya(:,j,iRm,iRc,iRk));
    end
end
end
end


%% Plot

%%%%% Separate type %%%%%
for iRk = 1:RkN
    subplot(RkN,1,iRk)
    plot(freq,xm(:,1,1,iRk))
    xline(N_freq,'--','DisplayName','Natural Frequency')
    title(['Rk=',num2str(Rk(iRk))])
end

%%%%% Same area %%%%%
% hold on
% for iRk = 1:RkN
%     plot(freq,xm(:,1,1,iRk),'DisplayName',strcat('Rk =',num2str(Rk(iRk))))
% end
% xline(N_freq,'--','DisplayName','Natural Frequency')
% legend()
% hold off

%% Functions

function [x1,x2,u1,u2]=RungeKutta(x1,x2,u1,u2,Rm,Rc,Rk,Rs,zm,tau,dtau)

    [Cx1_1,Cx2_1,Cu1_1,Cu2_1] = DifEqu(x1,x2,u1,u2,Rm,Rc,Rk,Rs,zm,tau);
    [Cx1_2,Cx2_2,Cu1_2,Cu2_2] = DifEqu(x1+Cx1_1*0.5*dtau,x2+Cx2_1*0.5*dtau,u1+Cu1_1*0.5*dtau,u2+Cu2_1*0.5*dtau,Rm,Rc,Rk,Rs,zm,tau+0.5*dtau);
    [Cx1_3,Cx2_3,Cu1_3,Cu2_3] = DifEqu(x1+Cx1_2*0.5*dtau,x2+Cx2_2*0.5*dtau,u1+Cu1_2*0.5*dtau,u2+Cu2_2*0.5*dtau,Rm,Rc,Rk,Rs,zm,tau+0.5*dtau);
    [Cx1_4,Cx2_4,Cu1_4,Cu2_4] = DifEqu(x1+Cx1_3*dtau,x2+Cx2_3*dtau,u1+Cu1_3*dtau,u2+Cu2_3*dtau,Rm,Rc,Rk,Rs,zm,tau+dtau);

    x1 = x1+dtau*(Cx1_1 + 2*Cx1_2 + 2*Cx1_3 + Cx1_4)/6;
    x2 = x2+dtau*(Cx2_1 + 2*Cx2_2 + 2*Cx2_3 + Cx2_4)/6;
    u1 = u1+dtau*(Cu1_1 + 2*Cu1_2 + 2*Cu1_3 + Cu1_4)/6;
    u2 = u2+dtau*(Cu2_1 + 2*Cu2_2 + 2*Cu2_3 + Cu2_4)/6;

end

function [dym,dya,dvm,dva] = DifEqu(ym,ya,vm,va,Rm,Rc,Rk,Rs,zm,tau)
    dym = vm; 
    dya = va;
    dvm = sin(Rs*tau)- 2*zm*vm-ym-Rc*2*zm*(vm-va)-Rk*(ym-ya);
    dva = -1/Rm*(Rc*2*zm*(va-vm)+Rk*(ya-ym));
end

結果

前述の通り2通りのプロットを用意したので順番に見てみよう。
今回はRkだけを3通りの値で変化させて周波数特性を出力した。
Rk = [ 0.1 , 1 , 10 ]

Rk = 0.1およびRk = 10にはピークが1つしか無いように見える。
しかし、よく見ると極小のピークが立っている。
また、破線が主系のみの固有振動数である。つまり、従系(動吸振器)を追加することで共振周波数がシフトすることが確認できた。

1.jpg
2.jpg

どちらのグラフも縦軸が変位、横軸が周波数でプロットしている。
このときの値は無次元化したものではなく、もとの微分方程式の値である。
すなわち、実際に設計に反映できる値である。

まとめ

今回の記事では動吸振器をモデルにした2自由度振動系の数値計算をmatlabで行った。
個人的にはmatlabはpythonよりも使いやすいと思う。
pythonと比べたとき、
・標準ライブラリが非常に豊富なので、追加インストールなしで使える。
・計算が速い(特に配列の計算)
変数の値を表示してくれる。(↓画像)
・複数のタスクを開いておける(計算とplotを分割出来る)
この4点が非常に優秀だと感じる。

キャプ.png

matlabの計算性能は非常に高いので、膨大なデータの計算をゴリゴリ回したい方は是非挑戦してみてほしい。

(完)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0