# Discrete Variables cause Step Size Not Real Error in NDSolve

I have, until recently, had great success using discrete variables to manage local changes in the definitions of the derivatives with NDSolve. Now, for reasons I don't entirely understand, this technique is not working for me.

I've tried to construct a small example to illustrate. This is as small as I've gotten.

I have four "modes". Each mode i is described by a function

g[x,i,t] = 1+1/(8 i^2)+t/i-x/i+Exp[-8 i x] cee[i][t]


with a scalar parameter cee[i]. The scalars cee[i] and associated scalars F[i] should evolve according to simple linear relationships.

The functions for two modes i and j cross at two points s[i,j] and s[j,i]. The issue arises when these two points converge to a single point. In this example s[2,3] and s[3,2] converge. That process dramatically slows NDSolve as the step size goes to 0.

To avoid that, I used a discrete variable to change the definition of the derivative of cee[3] when s[2,3] and s[3,2] get too close together. The new definition defines the derivative of cee[3] so that s[2,3] and s[3,2] remain the same distance apart, i.e, so that s[3,2]'[t] = s[2,3]'[t]

The discrete variable toggle[t] changes to 1 when the two are close and the definition of cee[3]'[t] is

cee[3]'[t] == (-1/3)*(1-toggle[t])+toggle[t](expression that ensures s[3,2]'[t] = s[2,3]'[t])

The issue: At the point the discrete variable changes to 1, NDSolve throws an NDSolve::ndsnr -- Step size not real error

Removing the discrete variable, stopping the integration when s[2,3] and s[3,2] get too close and restarting the integration with the new definition of cee[3]'[t] works fine.

My question is "What's the difference?" Isn't that in essence exactly what NDSolve does when the discrete variable changes? Why is it not working in this case? Any insight would be most welcome!

Rather than try to translate the largish example, I share it in the notebook in Wolfram cloud.

• Try it with the WhenEvent option "LocationMethod"->"StepEnd" for toggle. Commented Dec 3, 2021 at 18:03
• That did it! Simple. Thanks. But how do I accept your answer? I don't see the option. Commented Dec 4, 2021 at 22:30
• Comments can't be accepted. I wasn't sure you would be satisfied with the suggestion, so I didn't post it as an answer until now, after seeing your feedback. Commented Dec 4, 2021 at 22:58

The solution appears to be to use WhenEvent for toggle with option "LocationMethod" -> "StepEnd". The hint was that a step-size related error was connected to the particular WhenEvent, and that suggested the problem was in locating the event. The event invoked an action when a certain threshold was passed, and it did not seem to me that getting the location of the threshold exactly right was important.

[I apologize for not showing the complete code, since it's large and contained in an external link.]