Background: In the code that I am running I have a large number of differential equations that are dependent on several parameters and I am solving these using NDSolve
. As expected, as I change one of the key parameters in NDSolve the nature of the solutions changes.
To cut a long story short, I am hoping to find solutions to a wavefunction that has to be decaying so it can be normalised. By tuning the right parameters, I can find the values that allow the wavefunction to have evanescent behaviour. This involves using WhenEvent procedures to rule out solutions that become diverging or do not display the behaviour I want.
The Problem: I noticed that I wasn't getting the behaviour I expected in one given set of parameters. My WhenEvent
was set up to count the number of roots a given function went through and to stop integration at the 2n+1th root (for some integer n
that I control).
I noticed that the function crossed ever so slightly below the axes and indeed I checked it crossed by finding some small but distinctly negative values. However, WhenEvent
did not recognise these crossings and consequently did not stop the integration as expected.
I browsed the Help Files to the section on WhenEvent
and under Possible Issues I found the section on Arbitrarily Close Events. I followed the advice there to no avail, trying all the methods suggested and combinations thereof.
When I use the "DetectionMethod" -> "Interpolation"
setting I get the error
NDSolve::ecboo: The value of event condition function at r = 0.00010000000000006325034537697002037912824214855538481`50. was not True or False. The event will be considered inactive.
Minimal Working Example:
Copying my entire code into this page would not be of much use. I have come up with a small example in the form of a parabola that is just dipping below the origin:
NDSolve[{y'[x] - x^3 == 0, y[0] == -.0001,
WhenEvent[y[x] < 0, {"StopIntegration"}]}, y, {x, -3, 3}]
Plotting the above solution from -3 to 3 gives me the whole parabola, whereas I am expecting the solution to stop at x=0. The domain of y[x]
also shows me that the range is [-3,3].
Why is the WhenEvent
not picking up the two roots?
I know this is a very simplistic example and some of the solutions on the Help file could work but I am also looking for advice on what might be going wrong in my case. My solution does a very similar thing but its gradient is much more pronounced.
Reading up on the issue in other threads did not highlight a proper solution but this seems to be an issue on other versions too. I am working on version 10.3.0
Edit: So Michael2 fixed the problem with the minimal working example (never knew integration started from the boundary conditions!). However, the problems in my code are still present (the integration range is always positive so it was a bad example to choose).
In particular, whenever I let the Detection Method
be Automatic
the code runs and WhenEvents detect most root crossings. However, trying to change the method to Linear Interpolation
I get:
NDSolve::ecboo: The value of event condition function at r = 0.00010000000000006325034537697002037912824214855538481`50. was not True or False. The event will be considered inactive.
I have no idea what the error is telling me and why the condition is not evaluating as True or False with LinearInterpolation
when it did before. For this reason I have not marked the question as answered.
x == 0
, since this is not where the event you seem to be considering takes place. (I assume this is just a lack of precision; otherwise the simple way to stop is by integrating over{x, -3, 0}
. See if I interpreted it right in my answer. However, I wasn't sure exactly what interval of integration you were seeking.) $\endgroup$MaxStepFraction
,MaxStepSize
,PrecisionGoal
, andAccuracyGoal
. -- But it is also possible that there is an error in your code forWhenEvent
, because that is what tends to lead to the error you report. One would have to have the code to examine to see whether that is the case. $\endgroup$MaxStepSize
slowed the computation right down. $\endgroup$