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.
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
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}}]
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}]
Answered by Michael E2 on May 4, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP