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$
    – J. M.'s torpor
    Jun 9 '13 at 4:29
  • $\begingroup$ Im trying to solve a reaction diffusion equation with NDSolve, and reset the density function mid integration $\endgroup$
    – fernando
    Jun 9 '13 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
    Jun 9 '13 at 4:39
  • $\begingroup$ that's the code im trying $\endgroup$
    – fernando
    Jun 9 '13 at 4:39
  • $\begingroup$ Well, please edit that code into your post, instead of posting that in comments... $\endgroup$
    – J. M.'s torpor
    Jun 9 '13 at 4:43
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
    Jun 9 '13 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
    Jun 9 '13 at 5:53
  • $\begingroup$ I like the use of Sign[], but maybe the PDE will look nicer if you use Piecewise[]. $\endgroup$
    – J. M.'s torpor
    Jun 9 '13 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
    Jun 9 '13 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$
    – J. M.'s torpor
    Jun 9 '13 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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