MATLAB - 将正弦强制函数传递给ode45

时间:2016-07-04 16:23:54

标签: matlab ode numerical-integration

我是Matlab的新手,我甚至很难掌握基础知识。

我有一个功能myspring,它可以解决质量/弹簧系统的位置和速度,并具有阻尼和驱动力。我可以在运行k之前在命令窗口中指定弹簧刚度(c),阻尼系数(m)和质量(ode45)的值。我无法做的是定义一个强制函数(甚至像g = sin(t)这样的简单函数)并使用 作为强制函数,而不是将其写入myspring功能

有人可以帮忙吗?这是我的职责:

function pdot = myspring(t,p,c,k,m)

w = sqrt(k/m);

g = sin(t);  % This is the forcing function

pdot = zeros(size(p));
pdot(1) = p(2);
pdot(2) = g - c*p(2) - (w^2)*p(1);

end

以及我如何在命令窗口中使用它:

>> k = 2; c = 2; m = 4;
>> tspan = linspace(0,10,100);
>> x0 = [1 0];
>> [t,x] = ode45(@(t,p)myspring(t,p,c,k,m),tspan,x0);

这有效,但我想要的应该是这样的(我想):

function pdot = myspring(t,p,c,k,m,g)

w = sqrt(k/m);

pdot = zeros(size(p));
pdot(1) = p(2);
pdot(2) = g - c*p(2) - (w^2)*p(1);

end

然后

g = sin(t);
[t,x] = ode45(@(t,p)myspring(t,p,c,k,m,g),tspan,x0);

但我得到的是这个

In an assignment  A(:) = B, the number of elements in A and B must be the same.

Error in myspring (line 7)
pdot(2) = g - c*p(2) - (w^2)*p(1);

Error in @(t,p)myspring(t,p,c,k,m,g)

Error in odearguments (line 87)
f0 = feval(ode,t0,y0,args{:});   % ODE15I sets args{1} to yp0.

Error in ode45 (line 115)
    odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
霍希勒,谢谢你的回复。我可以按你的建议去做,但它有效。我现在面临另一个问题,我希望你能告诉我。

我有一个脚本,使用Morison方程计算由于波相互作用而在结构上产生的力。我给它一个任意的时间跨度开始。我想使用脚本计算的力F作为myspring的输入驱动力。这是我的Morison脚本:

H = 3.69;           % Wave height (m)
A = H/2;            % Wave amplitude (m)
Tw = 9.87;           % Wave period (s)
omega = (2*pi)/Tw;  % Angular frequency (rad/s)
lambda = 128.02;    % Wavelength (m)
k = (2*pi)/lambda;  % Wavenumber (1/m)
dw = 25;             % Water depth (m)
Cm = 2;             % Mass coefficient (-)
Cd = 0.7;           % Drag coefficient (-)
rho = 1025;         % Density of water (kg/m^3)
D = 3;              % Diameter of structure (m)

x = 0;              % Fix the position at x = 0 for simplicity


t = linspace(0,6*pi,n);   % Define the vector t with n time steps
eta = A*cos(k*x - omega*t); % Create the surface elevation vector with size equal to t

F_M = zeros(1,n); % Initiate an inertia force vector with same dimension as t
F_D = zeros(1,n); % Initiate a drag force vector with same dimension as t
F = zeros(1,n); % Initiate a total force vector with same dimension as t

fun_inertia = @(z)cosh(k*(z+dw));  % Define the inertia function to be integrated
fun_drag = @(z)(cosh(k*(z+dw)).*abs(cosh(k*(z+dw))));   % Define the drag function to be integrated

for i = 1:n
    F_D(i) = abs(((H*pi)/Tw) * (1/sinh(k*dw)) * cos(k*x - omega*t(i))) * ((H*pi)/Tw) * (1/sinh(k*dw)) * cos(k*x - omega*t(i)) * integral(fun_drag,-dw,eta(i));
    F_M(i) = (Cm*rho*pi*(D^2)/4) * ((2*H*pi^2)/(Tw^2)) * (1/(sin(k*dw))) * sin(k*x - omega*t(i)) * integral(fun_inertia,-dw,eta(i));
    F(i) = F_D(i) + F_M(i);
end

非常感谢任何进一步的建议。

1 个答案:

答案 0 :(得分:2)

您无法预先计算强制功能。这取决于ode45确定的时间。您需要将g定义为函数并将a handle to it传递到集成函数中:

...
g = @(t)sin(t);
[t,x] = ode45(@(t,p)myspring(t,p,c,k,m,g),tspan,x0);

然后在集成函数中调用它,传入当前时间:

...
pdot(2) = g(t) - c*p(2) - (w^2)*p(1);
...