15
$\begingroup$

Can WhenEvent be used to reset the conditions on a PDE at a given time? How would the syntax of that be?

This is the code I`m using

r = 2;
d2 = 1;
l = 5;
sol = NDSolve[{Derivative[0, 1][n][x, t] ==
               d2 Derivative[2, 0][n][x, t] + r*n[x, t]*(1 - n[x, t]),
               n[x, 0] == 0.1*x*(1 - x/l), n[0, t] == 0, n[l, t] == 0,
               WhenEvent[t == 50, n[x, t] -> 0]}, {n}, {x, 0, l}, {t, 0, tmax}]
$\endgroup$
8
  • $\begingroup$ Could you maybe specify the particular PDE you're working with, so that it's easier for us to show you how? $\endgroup$ Commented Jun 9, 2013 at 4:29
  • $\begingroup$ Im trying to solve a reaction diffusion equation with NDSolve, and reset the density function mid integration $\endgroup$
    – fernando
    Commented Jun 9, 2013 at 4:36
  • $\begingroup$ sol = NDSolve[{ \!( *SubscriptBox[([PartialD]), (t)](n[x, t])) == d2*\!( *SubscriptBox[([PartialD]), (x, x)](n[x, t])) + r*n[x, t]*(1 - n[x, t]), n[x, 0] == 0.1*x*(1 - x/l), n[0, t] == 0, n[l, t] == 0, WhenEvent[t == 50, n[x, t] -> 0]}, {n}, {x, 0, l}, {t, 0, tmax}, $\endgroup$
    – fernando
    Commented Jun 9, 2013 at 4:39
  • $\begingroup$ that's the code im trying $\endgroup$
    – fernando
    Commented Jun 9, 2013 at 4:39
  • $\begingroup$ Well, please edit that code into your post, instead of posting that in comments... $\endgroup$ Commented Jun 9, 2013 at 4:43

1 Answer 1

17
$\begingroup$

According to the error message:

NDSolve::nlnum1: "The function value {0} is not a list of numbers with dimensions {25} when the arguments are {50.,{<<25>>}."

I think you should feed a 25-length list of 0 to n[x,t] in the WhenEvent:

WhenEvent[t > 50, n[x, t] -> ConstantArray[0, 25]]

Plot the result:

Plot3D[Evaluate[n[x, t] /. sol], {x, 0, l}, {t, 0, 100}, PlotPoints -> 50]

enter image description here

Edit:

According to the documentation, NDSolve automatically does processing for discontinuous functions like Sign, so here an alternative way which do not require manual specifying the number of grid nodes (i.e. 25):

sol2 = NDSolve[{
   Derivative[0, 1][n][x, t] ==
             d2*Derivative[2, 0][n][x, t] + 
             r*Sign[50 - t]*n[x, t]*(1 - Sign[50 - t]*n[x, t]),
    n[x, 0] == 0.1*x*(1 - x/l),
    n[0, t] == 0, 
       n[l, t] == 0},
   {n}, {x, 0, l}, {t, 0, 100}]

Note the difference near the discontinuity line between this solution and sol by above WhenEvent:

Show[
 MapThread[Plot3D[
    Evaluate[n[x, t] /. #1], {x, 0, l}, {t, 49, 53},
    PlotPoints -> 50, PlotStyle -> None,
    MeshFunctions -> (#1 &), MeshStyle -> #2,
    BoundaryStyle -> None, PlotRange -> All
    ] &,
  {{sol, sol2}, {Red, Blue}}
  ]]

enter image description here

Edit 2:

Using WhenEvent with automatic detecting the x-grid:

<< DifferentialEquations`InterpolatingFunctionAnatomy`
Clear[xGridExtractor]
xGridExtractor[f_] := InterpolatingFunctionCoordinates[Head[f]][[1]]

sol = NDSolve[
        {
         Derivative[0, 1][n][x, t] == d2*Derivative[2, 0][n][x, t] + r*n[x, t]*(1-n[x, t]), 
         n[x, 0] == 0.1*x*(1 - x/l),
         n[0, t] == 0,
         n[l, t] == 0, 
         WhenEvent[t > 50, n[x, t] -> 0*xGridExtractor[n[x, t]]]
        },
        {n}, {x, 0, l}, {t, 0, 100}]

Edit 3:

According to OP's comment, here is how to reset the initial condition along $t=50$ in a more general sense:

sol = NDSolve[
        {
         Derivative[0, 1][n][x, t] == d2*Derivative[2, 0][n][x, t] + r*n[x, t]*(1-n[x, t]), 
         n[x, 0] == 0.1*x*(1 - x/l),
         n[0, t] == 0,
         n[l, t] == 0, 
         WhenEvent[t > 50, n[x, t] -> (.5 Head[n[x, t]] /@ xGridExtractor[n[x, t]])]
        },
        {n}, {x, 0, l}, {t, 0, 100}]

Plot3D[Evaluate[n[x, t] /. sol], {x, 0, l}, {t, 49, 51},
     PlotPoints -> 50, MeshFunctions -> {#2 &, #3 &}, Exclusions -> t == 50]

half value

$\endgroup$
14
  • $\begingroup$ +1. I was just writing such an answer! The array seems to reinitialize the values of n[x, 50] along the line 0 <= x <= l -- probably the interpolation grid. $\endgroup$
    – Michael E2
    Commented Jun 9, 2013 at 5:40
  • $\begingroup$ @MichaelE2 Thanks and agree. I think there should be an alternative way which does not require manual specifying the number of grid nodes. $\endgroup$
    – Silvia
    Commented Jun 9, 2013 at 5:53
  • $\begingroup$ I like the use of Sign[], but maybe the PDE will look nicer if you use Piecewise[]. $\endgroup$ Commented Jun 9, 2013 at 20:26
  • $\begingroup$ @0x4A4D I just tried Piecewise, and I think I'd prefer the WhenEvent version. Neither Sign nor Piecewise are as good as WhenEvent near the discontinuity interface. $\endgroup$
    – Silvia
    Commented Jun 9, 2013 at 20:36
  • $\begingroup$ That's too bad. I was hoping for an alternative that'd also work in earlier versions of Mathematica. (I'm still on version 8.) $\endgroup$ Commented Jun 9, 2013 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.