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

Another solution is to use Simplify`PWToUnitStep:

s1 = NDSolve[{equa00 // Simplify`PWToUnitStep, x[0] == 1, x'[0] == 1}, x, {t, 0, 50}]
$\endgroup$
  • $\begingroup$ it runs successfully in verson 7 and thanks a lot! $\endgroup$ – dcydhb Nov 6 '19 at 8:44
5
$\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$
  • $\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 Nov 5 '19 at 12:44
  • $\begingroup$ @dcydhb IIRC "EquationSimplification" -> "Residual" is introduced in v9. $\endgroup$ – xzczd Nov 5 '19 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 Nov 5 '19 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 Nov 5 '19 at 14:11
  • $\begingroup$ i don't konw how to use @, thanks a lot! $\endgroup$ – dcydhb Nov 6 '19 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, privacy policy and cookie policy

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