Failure when using ode15i : not meeting integration tolerances
5 ビュー (過去 30 日間)
古いコメントを表示
Hello !
Thanks to your answers, I have been able to solve a DAE using ode15i. The code runs but only until a specific time, and after it it stops:
My code solves the following DAE :
d²x/dt² = 1/m * (- f2(x-x1, dx/dt - dx1/dt))
0 = f2(x-x1, dx/dt - dx1/dt) - f1(x1,dx1/dt)
and f1 and f2 are functions calculating the force corresponding to x1,x and dx/dt, dx1/dt.
f1 and f2 look like this :
function force = f1(x - x1, dx - dx1)
if dx - dx1 <= 0 %COMPRESSION
force = ... (a polynom P(x - x1))
else %DETENTE
force = ... (another polynom P(x - x1))
end
I then use it in my DAE :
function res = f(t,Y,dY)
% Y = (x; x1; dx) and dY = (dx; dx1; d²x)
course1 = l0(1) - Y(2);
coursetot = l0(1) + l0(2) - Y(1);
course2 = coursetot - course1;
forcemi79 = f1(course1, dY(2))
forcemi20 = f_MI20ode15i(course2,Y(3)-dY(2));
res = [dY(1) - Y(3);
- forcemi20 + forcemi79;
dY(3) - 1/m_materiel*(forcemi20)];
And then I use ode15i :
sol = ode15i(@f,tspan,y0,yp0)
But when dx - dx1 goes from negative to positive, the code stops, with this error :
Warning: Failure at t=5.111363e-01. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.815921e-15) at time t.
> In ode15i at 406
In wagon79face20 at 31
I don't understand how I can change f1 and f2 in order for it to run anyway ?
Thank you for your help !
6 件のコメント
Walter Roberson
2022 年 7 月 22 日
forcemi79 = ...a polynom P(course)
elseif course<=...
The three dots at in the forcemi79 assignment act as continuation markers. The rest of that line is ignored, and the next line is treated as if it was part of the same line, so you effectively have a line
forcemi79 = elseif course<= forcemi79 else forcemi79=0
which is not valid syntax.
Reminder: if you are hoping that someone can debug your code, they need your actual code to test with.
採用された回答
Walter Roberson
2022 年 7 月 22 日
I am a lot less familiar with ode15i, but I think your equations need to have continuous derivatives, at least one step. Which would mean that your different force functions need to be arranged to have at least first (and possibly second) derivatives continuous with each other across vrel changing between compression and relaxation . (The same problem occurs in friction system in effectively switching the direction of opposition to motion.)
If you were using ode45() or ode23s() or similar, then I would be certain that this is a problem; however, I see that ode15i uses a different calculation system that I know less about.
When you change state non-smoothly then you risk exactly the kind of error you see.
The work-around is to use an event function to detect each time that you would change state, and have it terminate the call there; then take the output of that, make any necessary adjustments to the boundary conditions (such as reflecting a bounce or an input of energy), and then call the ode* function again to continue from that time.
The rule for ode45() and ode23s() and similar is not exactly that you cannot use if statements: however if the if statements do not lead to smooth first and second derivatives at that location then you need to arrange so that the discontinuity of state does not occur within one call
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Numerical Integration and Differential Equations についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!