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

2 views (last 30 days)
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?

Answers (2)

Walter Roberson
Walter Roberson on 31 Mar 2025
Edited: Walter Roberson on 31 Mar 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 on 31 Mar 2025
Edited: Torsten on 31 Mar 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 Comments
Arne
Arne on 2 Apr 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 on 2 Apr 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.

Sign in to comment.

Categories

Find more on Geology in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!