# 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.0520876770316Adding 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
Sort By:
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.