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

2 ビュー (過去 30 日間)
Arne
Arne 2025 年 3 月 31 日
コメント済み: Torsten 2025 年 4 月 2 日
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
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.

Torsten
Torsten 2025 年 3 月 31 日
編集済み: Torsten 2025 年 3 月 31 日
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
Arne 2025 年 4 月 2 日

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 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.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeGeology についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by