# Constraining function found by NDSolve to stay positive

I am trying to constrain my variables in NDSolve so that they stay positive for the integration interval. Is is possible to do that? Using Assumptions as in Simplify does not work. WhenEvent also does not help, as it just finds the event once.

Here is a code snippet of a minimal example:

a = 10;
sol = NDSolve[{x'[t] == -10, x[0] == 10}, x, {t, 0, 10}];
Plot[Evaluate[x[t] /. sol], {t, 0, 10}, PlotRange -> All]


What I would like to get out is a function, that linearly decreases from 10 to 0 and stays on 0 -- instead of turning negative.

### Edit

To clarify the question: I am using Mathematica for fast prototyping. In a C environment I can modify the time integration with an additional step, like if(x<0){ x=1e-10; } to ensure my variable does not turn negative. So I am looking for a way to introduce a lower bound into my system.

My full system consists of a system of 1st order nonlinear ODEs, which represent positive real quantities. I am aware that this modification will change the resulting solutions. The above just provides a minimal example of what I am looking for.

Changing the rhs as suggested below will unfortunately not do the trick, as it only adjusts the rate of change but does not introduce a lower bound for the solution. (Although, strictly speaking this procedure will result in a solution I was describing above ;)

-
If x'[t]== -10 then x[t] will get to 0 after one second (starting form x[0] == 10). It seems that a "positive" solution isn't possible –  belisarius Apr 10 at 5:07
This question appears to be off-topic because the OP's problem does not really concern Mathematica, but results from a misconception in the underlying mathematics. –  m_goldberg Apr 10 at 10:58

Here are couple of ways to do what the OP want. As was pointed out by @belisarius, your differential equation is inconsistent with x[t] being constant. I can think of two ways to deal with this, either stop integration or change the differential equation when the condition is reached.

### Method 1

Here the derivative parameter is a[t] and changes when the event x[t] == 0 is reached.

Clear[a];
sol = NDSolve[{x'[t] == -a[t], x[0] == 10, a'[t] == 0, a[0] == 10,
WhenEvent[x[t] == 0, a[t] -> 0]}, x, {t, 0, 10}];

Plot[Evaluate[x[t] /. sol], {t, 0, 10}, PlotRange -> All]


### Method 2

In this method, we stop integration at the event and use Piecewise to complete the solution. This method may not work as is in the OP's use case. But instead of the default value of 0 used by Piecewise, another function could be supplied, such as the solution to another differential equation.

solval = Piecewise[{{#[t], #[[1, 1]] <= t <= #[[1, 2]] &@#["Domain"]}}] &@
NDSolveValue[{x'[t] == -10, x[0] == 10,
WhenEvent[x[t] < 0, "StopIntegration"]}, x, {t, 0, 10}];

Plot[solval, {t, 0, 10}, PlotRange -> All]


### Update: Method 2'

Similar to Method 2, but using "ExtrapolationHandler" instead of Piecewise:

solval = NDSolveValue[{x'[t] == -10, x[0] == 10,
WhenEvent[x[t] < 0, "StopIntegration"]}, x, {t, 0, 10},
"ExtrapolationHandler" -> {0 &, "WarningMessage" -> False}]


In all cases the graphics output is the same:

-

Of course belisarius is right with his comment that the ODE in your example doesn't have a positive solution. I guess that you want to actually solve a different equation, and this should do what I think you try to achieve:

a = 10;
sol = NDSolve[{x'[t] == If[x[t] >= 0, -10, 0], x[0] == 10}, x, {t, 0, 10}];
Plot[Evaluate[x[t] /. sol], {t, 0, 10}, PlotRange -> All]


I also don't think that what you say about WhenEvent is true: it very well can find events more than once. I also guess that your example is most probably simplified too much and for a more complicated example WhenEvent certainly would be the way to go. What is the code you did try with WhenEvent?

-