Message Boards Message Boards

GROUPS:

Avoid issue while using Mod[] in NDSolve[]?

Posted 2 months ago
318 Views
|
2 Replies
|
2 Total Likes
|

Let us assume a simple rotation motion, when angular acceleration az somewhat depends on angle Phi[t] and set as linear interpolation function in range of 0..360 degrees. To not come out from interpolation range let angle Phi to be truncated to proper range by Mod[Phi][t], 360]:

az = Interpolation[{{0., 1.}, {90., 4}, {180., 7.}, {270., 4.}, {360.,
      1.}}, InterpolationOrder -> 1];

{\[Omega]s, \[CurlyPhi]s} = NDSolveValue[{

   \!\(
\*SubscriptBox[\(\[PartialD]\), \(t\)]\ \(\[Omega][
      t]\)\) == (az[Mod[\[CurlyPhi][t], 360]] + 10000),
   \!\(
\*SubscriptBox[\(\[PartialD]\), \(t\)]\ \(\[CurlyPhi][
      t]\)\) == \[Omega][t],

   \[CurlyPhi][0] == 359, \[Omega][0] == 
    390 }, {\[Omega], \[CurlyPhi]}, {t, 0, 0.0029}]

Let run it, and we get

InterpolatingFunction::dmval: Input value {360.052} lies outside the range of data in the interpolating function. Extrapolation will be used.

This is quite weird result - we have truncate phi by 360 and got 360.0520876770316`

Adding

EvaluationMonitor :> 
 Print[t, "  ", \[CurlyPhi][t], "  ", Mod[\[CurlyPhi][t], 360]]

Gives list like

...
0.00203059  359.813  359.813
0.00232059  359.932  359.932
InterpolatingFunction::dmval: Input value {360.052} lies outside the range of data in the interpolating function. Extrapolation will be used.
0.0026103  360.052  0.0520877
0.00248493  360.  360.
0.00248493  360.  0.
0.00248493  360.  0.
0.00248493  360.  2.19102*10^-6

Mod[] works fine in the EvaluationMonitor, but fails in main NDSolve loop.

Can anyone tell the reason of such behavior and how to fix it?

2 Replies
Posted 2 months ago

Likely, this is just a toy problem you have given, and your actual problem is more complicated. But for this simple case, you could have just built a periodic interpolant at the outset, so you wouldn't need Mod[]:

az = Interpolation[{{0., 1.}, {90., 4}, {180., 7.}, {270., 4.}, {360., 1.}},
                   InterpolationOrder -> 1, PeriodicInterpolation -> True];

From here, we can easily simplify your NDSolve[] call:

φs = NDSolveValue[{φ''[t] == az[φ[t]] + 10000, φ[0] == 359, φ'[0] == 390},
                  φ, {t, 0, 0.0029}];

Note that you don't need to convert to a system of first order equations; NDSolve[] is perfectly capable of handling high-order derivatives directly. From there, you can just evaluate ωs = φs' if you still need the derivative as a separate function.

POSTED BY: J. M.
Answer
Posted 2 months ago

I still wonder why Mod[] gives wrong result.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract