eventfunction for stopping solver when output becomes complex doesn't work
显示 更早的评论
I am trying to solve the following DE;
function [v] = DE(t, y, Vb0, lambda, mb, rhog0, Cw)
% vaste parameters
LoadConstants
% tussenberekeningen
% krachten
Fa = rhol0*Vb0*g;
Fzk = lambda*y*g;
Fzb = (rhog0*Vb0+mb)*g;
% hoogteafhankelijke parameters
Vb = Vb0*(1-y*L/Tl0).^(1-(g*Ml/(R*L)));
rhol = rhol0*(1-y*L/Tl0).^((g*Ml/(R*L))-1);
rb = ((3*Vb)/(4*pi)).^(1/3);
Ab = pi*rb.^2;
% snelheid
v = sqrt(2/3)*sqrt((Fa-Fzb-Fzk)./(Ab*Cw.*rhol));
end
I am doing it using the following function:
function [t, y] = SolveDE(Vb0, lambda, mb, rhog0, Cw)
tspan = [0 5000];
y0 = 0;
options = odeset('Events', @stop);
[t, y] = ode45(@(t, y) DE(t,y, Vb0, lambda, mb, rhog0, Cw),...
tspan, y0, options);
end
with the stop-function defined as:
function [value, isterminal, direction] = stop(t, y)
value = isreal(y) && y <= 11000;
isterminal = 1;
direction = 0;
if imag(y) ~= 0
disp(['STOP: y is imaginair geworden bij t = ', num2str(t)]);
elseif y > 11000
disp(['STOP: y is groter dan 11km geworden bij t = ', num2str(t)]);
end
end
the eventfunction works perfect when is it y going above 11km that stops the solver, however when y becoming complex happens first something weird happens. I get the message that the stopfunction detected y becoming complex but is still continues for a bit resulting in a complex outputvector y. The values are in the form x + 0.0000000000000i. Can i fix this?
回答(2 个)
Walter Roberson
2025-3-31
编辑:Walter Roberson
2025-3-31
Try
value = [real(y) - 11000;
imag(y)]
isterminal = [1;
1];
direction = [1;
0];
Note that integration will not stop as soon as it encounters an event: instead, once it encounters an event, it searches around trying to find the exact boundary so that it can stop at the boundary.
Try
options = odeset('Events', @(t,y)stop(t, y, Vb0, lambda, mb, rhog0, Cw));
[t, y] = ode45(@(t, y) DE(t,y, Vb0, lambda, mb, rhog0, Cw),...
tspan, y0, options);
function [value, isterminal, direction] = stop(t, y, Vb0, lambda, mb, rhog0, Cw)
% vaste parameters
LoadConstants
% tussenberekeningen
% krachten
Fa = rhol0*Vb0*g;
Fzk = lambda*y*g;
Fzb = (rhog0*Vb0+mb)*g;
% hoogteafhankelijke parameters
Vb = Vb0*(1-y*L/Tl0).^(1-(g*Ml/(R*L)));
rhol = rhol0*(1-y*L/Tl0).^((g*Ml/(R*L))-1);
rb = ((3*Vb)/(4*pi)).^(1/3);
Ab = pi*rb.^2;
tol = 1e-3;
value = [1-y*L/Tl0-tol;Fa-Fzb-Fzk-tol;y-11000]
isterminal = [1;1;1];
direction = [0;0;0];
end
If this does not work, we must have executable code for testing.
4 个评论
Arne
2025-4-1
Vb0 = 10000;
lambda = 0.125;
mb = (20*10^-3)*(36*pi*Vb0^2)^(1/3);
rhog0 = 0.169;
Cw = 0.285;
[t,y] = SolveDE(Vb0, lambda, mb, rhog0, Cw)
plot(t,y)
function [t, y] = SolveDE(Vb0, lambda, mb, rhog0, Cw)
tspan = [0 5000];
y0 = 0;
options = odeset('Events', @(t,y)stop(t, y, Vb0, lambda, mb, rhog0, Cw));
[t, y] = ode45(@(t, y) DE(t,y, Vb0, lambda, mb, rhog0, Cw),...
tspan, y0, options);
end
function [v] = DE(t, y, Vb0, lambda, mb, rhog0, Cw)
% vaste parameters
rhol0 = 1.225;
L = 0.0065;
Tl0 =288.15;
R = 8.314;
g = 9.81;
Ml = 0.02896;
Pl0 =101325;
% tussenberekeningen
% krachten
Fa = rhol0*Vb0*g;
Fzk = lambda*y*g;
Fzb = (rhog0*Vb0+mb)*g;
% hoogteafhankelijke parameters
Vb = Vb0*(1-y*L/Tl0).^(1-(g*Ml/(R*L)));
rhol = rhol0*(1-y*L/Tl0).^((g*Ml/(R*L))-1);
rb = ((3*Vb)/(4*pi)).^(1/3);
Ab = pi*rb.^2;
% snelheid
v = sqrt(2/3)*sqrt(abs(Fa-Fzb-Fzk)./(Ab*Cw.*rhol));
end
function [value, isterminal, direction] = stop(t, y, Vb0, lambda, mb, rhog0, Cw)
% vaste parameters
rhol0 = 1.225;
L = 0.0065;
Tl0 =288.15;
R = 8.314;
g = 9.81;
Ml = 0.02896;
Pl0 =101325;
% tussenberekeningen
% krachten
Fa = rhol0*Vb0*g;
Fzk = lambda*y*g;
Fzb = (rhog0*Vb0+mb)*g;
value = [1-y*L/Tl0;Fa-Fzb-Fzk;y-11000];
isterminal = [1;1;1];
direction = [0;0;0];
end
Arne
2025-4-2
Torsten
2025-4-2
Yes for big values of Vb0 the output of the DE never bevomes complex.
I tested that it also works for small values of Vb0. But if you already made the code work, it's fine.
类别
在 帮助中心 和 File Exchange 中查找有关 Geology 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
