eventfunction for stopping solver when output becomes complex doesn't work

2 visualizaciones (últimos 30 días)
Arne
Arne el 31 de Mzo. de 2025
Comentada: Torsten el 2 de Abr. de 2025
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?

Respuestas (2)

Walter Roberson
Walter Roberson el 31 de Mzo. de 2025
Editada: Walter Roberson el 31 de Mzo. de 2025
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.

Torsten
Torsten el 31 de Mzo. de 2025
Editada: Torsten el 31 de Mzo. de 2025
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 comentarios
Arne
Arne el 2 de Abr. de 2025

Yes for big values of Vb0 the output of the DE never bevomes complex. However i managed to fix the problem by adding Reltol and Abstol arguments with high requirements in the odeset function.

Torsten
Torsten el 2 de Abr. de 2025
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.

Iniciar sesión para comentar.

Categorías

Más información sobre Geology en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by