我在 MATLAB 中使用 ode45 运行一组 ODE,我需要保存其中一个变量(这不是导数)以供以后使用。我正在使用函数“assignin”在基础工作区中分配一个临时变量,并在每一步更新它。这似乎可行,但是,数组的大小与从 ode45 获取的解向量的大小不匹配。例如,我有以下嵌套函数:
function [Z,Y] = droplet_momentum(theta,K,G,P,zspan,Y0)
options = odeset('RelTol',1e-7,'AbsTol',1e-7);
[Z,Y] = ode45(@momentum,zspan,Y0,options);
function DY = momentum(z,y)
DY = zeros(4,1);
%Entrained Total Velocity
Ve = sin(theta)*(y(4));
%Total Relative Velocity
Urs = sqrt((y(1) - y(4))^2 + (y(2) - Ve*cos(theta))^2 + (y(3))^2);
%Coefficients
PSI = K*Urs/y(1);
PHI = P*Urs/y(1);
%Liquid Axial Velocity
DY(1) = PSI*sign(y(1) - y(4))*(1 + (1/6)*(abs(y(1) - y(4))*G)^(2/3));
%Liquid Radial Velocity
DY(2) = PSI*sign(y(2) - Ve*cos(theta))*(1 + (1/6)*(abs(y(2) - ...
Ve*cos(theta))*G)^(2/3));
%Liquid Tangential Velocity
DY(3) = PSI*sign(y(3))*(1 + (1/6)*(abs(y(3))*G)^(2/3));
%Gaseous Axial Velocity
DY(4) = (1/z/y(4))*((PHI/z)*sign(y(1) - y(4))*(1 + ...
(1/6)*(abs(y(1) - y(4))*G)^(2/3)) + Ve*Ve - y(4)*y(4));
assignin('base','Ve_step',Ve);
evalin('base','Ve_out(end+1) = Ve_step');
end
end
在上面的代码中,theta(弧度)、K(负值)、P 和 G 是常数,为了这个例子,可以取任何值。Zspan 只是 ODE 求解器的积分时间步长,Y0 是初始条件向量 (4x1)。同样,为了这个例子,这些可以取任何合理的值。现在在主文件中,使用以下内容调用该函数:
Ve_out = 0;
[Z,Y] = droplet_momentum(theta,K,G,P,zspan,Y0);
Ve_out = Ve_out(2:end);
这个方法没有被 MATLAB 抱怨,但问题是 Ve_out 的大小与 Z 或 Y 的大小不一样。原因是因为 MATLAB 对其算法多次调用 ODE 函数,所以解决方案是将比 Ve_out 略小。正如 am304 所建议的那样,我可以通过给 ode 函数一个 Z 和 Y 向量(例如 DY = 动量(Z,Y))来简单地计算 DY,但是,我需要使用“assignin”(或类似方法)来解决这个问题,因为另一个这个问题的版本在 DY 和 Ve 之间存在隐式依赖性,并且在每次迭代时计算 DY 的计算成本太高(我将在多次迭代中运行这个问题)。