TransWikia.com

NDSolve will try solving the system as differential-algebraic equations but it didn't get the solution

Mathematica Asked by dcydhb on May 4, 2021

Please help me deal with this kind of question about ODEs.
My codes are as follows

m = 100;
a = D[x[t], {t, 2}];
t1up = 2 x''[t] + 1/2 (490 + 34 x''[t] + 2 (490 + 50 x''[t]));
t1down = 490 + 53 x''[t];
t1 = Piecewise[{{t1up, x'[t] >= 0}, {t1down, x'[t] < 0}}]
equa00 = t1 == m*a
t0 = 50;
s1 = NDSolve[{equa00, x[0] == 1, x'[0] == 1}, x, {t, 0, 50}]

However, I get an error:

NDSolve::ntdvdae: Cannot solve to find an explicit formula for the derivatives. NDSolve will try solving the system as differential-algebraic equations. >>

So is it a differential-algebraic equation? How to solve it?

I have another question, too: How to plot the t1-t figure after we get the s1?
I have tried the following codes:

t1upvalue = (t1up /. {x'[t] -> (x'[t] /. s1), x''[t] -> (x''[t] /. s1)})
t1downvalue = (t1down /. {x'[t] -> (x'[t] /. s1), x''[t] -> (x''[t] /. s1)})
t1value = Piecewise[{{t1upvalue, (x'[t] /. s1) >= 0}, {t1downvalue, (x'[t] /. s1) < 0}}],
Plot[t1value[[1]], {t, 0, t0},PlotRange -> All]

However it doesn’t work.

3 Answers

Another solution is to use Simplify`PWToUnitStep:

s1 = NDSolve[{equa00 // Simplify`PWToUnitStep, x[0] == 1, x'[0] == 1}, x, {t, 0, 50}]

Correct answer by xzczd on May 4, 2021

Changing the last line to:

s1 = NDSolve[{equa00, x[0] == 1, x'[0] == 1}, x, {t, 0, 50}, SolveDelayed -> True]

or

s1 = NDSolve[{equa00, x[0] == 1, x'[0] == 1}, x, {t, 0, 50}, 
  Method -> {"EquationSimplification" -> "Residual"}]

seems help for your problem.

In reponse to updated question on plot slution

To plot your solution, maybe this is what you want?

Remove["Global`*"] // Quiet;
m = 100;
a = D[x[t], {t, 2}];
t1up = 2 x''[t] + 1/2 (490 + 34 x''[t] + 2 (490 + 50 x''[t]));
t1down = 490 + 53 x''[t];
t1 = Piecewise[{{t1up, x'[t] >= 0}, {t1down, x'[t] < 0}}];
equa00 = t1 == m*a;
t0 = 50;
(*s1 = NDSolveValue[{equa00 // Simplify`PWToUnitStep, x[0] == 1, 
    x'[0] == 1}, x, {t, 0, 50}];*)
s1 = x /.First@NDSolve[{equa00 // Simplify`PWToUnitStep, x[0] == 1, 
 x'[0] == 1}, x, {t, 0, 50}];
sAll = {x[t] -> s1[t], x'[t] -> s1'[t], x''[t] -> s1''[t]};

t1upvalue = t1up /. sAll;
t1downvalue = t1down /. sAll;
t1value = 
 Piecewise[{{t1upvalue, s1'[t] >= 0}, {t1downvalue, s1'[t] < 0}}];
Plot[t1value, {t, 0, t0}, PlotRange -> All]

Answered by xinxin guo on May 4, 2021

Here is the sort of thing I meant in my comment:

1. Get a single piecewise function

constraint = equa00 /. Equal -> Subtract // PiecewiseExpand

enter image description here

2. Solve each piece for x''[t]

solvexpp = x''[t] /. First@Solve[# == 0, x''[t]] &;
newode = x''[t] == MapAt[solvexpp, constraint, {{-1}, {1, 1, 1}}]

Mathematica graphics

A PiecewiseFunction can have more pieces. You can add the part indices to the list {{-1}, {1, 1, 1}}. MapAt was updated in V10 to allow the following to handle arbitrarily many pieces. (I don't think this works in earlier versions, but remembering so far back is not reliable.)

newode = x''[t] == MapAt[solvexpp, constraint, {{-1}, {1, All, 1}}]

If MapAt doesn't work in V7, try ReplacePart:

newode = x''[t] == ReplacePart[constraint, {
    {-1} -> solvexpp[constraint[[-1]]],
    {1, 1, 1} -> solvexpp[constraint[[1, 1, 1]]]}]

3. Integrate

s1 = NDSolve[{newode, x[0] == 1, x'[0] == 1}, x, {t, 0, 50}]

enter image description here

Answered by Michael E2 on May 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP