4
$\begingroup$

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.

$\endgroup$
5
  • 1
    $\begingroup$ Which version are you in? In v12 and v11.3 I get the ndnum warning. $\endgroup$
    – xzczd
    Commented Nov 5, 2019 at 11:47
  • 1
    $\begingroup$ my answer is is in version 7. $\endgroup$
    – dcydhb
    Commented Nov 5, 2019 at 12:48
  • $\begingroup$ Does Solve[equa00, x''[t]] work in V7? Does the "EventLocator"method for NDSolve work in V7? $\endgroup$
    – Michael E2
    Commented Nov 5, 2019 at 14:35
  • $\begingroup$ @Michael E2,what do you mean ,i have never used Solve and EventLocator $\endgroup$
    – dcydhb
    Commented Nov 6, 2019 at 8:22
  • $\begingroup$ this question has been solved but there are some question related mathematica.stackexchange.com/questions/209122/… $\endgroup$
    – dcydhb
    Commented Nov 6, 2019 at 8:43

3 Answers 3

8
$\begingroup$

Another solution is to use Simplify`PWToUnitStep:

s1 = NDSolve[{equa00 // Simplify`PWToUnitStep, x[0] == 1, x'[0] == 1}, x, {t, 0, 50}]
$\endgroup$
1
  • $\begingroup$ it runs successfully in verson 7 and thanks a lot! $\endgroup$
    – dcydhb
    Commented Nov 6, 2019 at 8:44
6
$\begingroup$

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]
$\endgroup$
5
  • $\begingroup$ the SolveDelayed -> True can help but the Method -> {"EquationSimplification" -> "Residual"} can't in version 7 with tips NDSolve::bdmtd: The value of the option Method -> {EquationSimplification->Residual} is not a known built-in method, a symbol that could be a user-defined method, or a list with a name followed by method options. >> $\endgroup$
    – dcydhb
    Commented Nov 5, 2019 at 12:44
  • $\begingroup$ @dcydhb IIRC "EquationSimplification" -> "Residual" is introduced in v9. $\endgroup$
    – xzczd
    Commented Nov 5, 2019 at 13:00
  • $\begingroup$ thanks for your Supplement but because there is no NDSolveValue in version 7and i use the First@NDSolve instead HOWEVER it doesn't ,so is there a way that i can use it version 7 $\endgroup$
    – dcydhb
    Commented Nov 5, 2019 at 13:57
  • $\begingroup$ I updated the code. After First@NDSolve, you can then use Replace (/.) to make s1 a pure function. $\endgroup$
    – xinxin guo
    Commented Nov 5, 2019 at 14:11
  • $\begingroup$ i don't konw how to use @, thanks a lot! $\endgroup$
    – dcydhb
    Commented Nov 6, 2019 at 8:23
1
$\begingroup$

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.