Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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}]
share|improve this question
    
Could you maybe specify the particular PDE you're working with, so that it's easier for us to show you how? –  J. M. Jun 9 '13 at 4:29
    
Im trying to solve a reaction diffusion equation with NDSolve, and reset the density function mid integration –  fernando Jun 9 '13 at 4:36
    
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}, –  fernando Jun 9 '13 at 4:39
    
that's the code im trying –  fernando Jun 9 '13 at 4:39
    
Well, please edit that code into your post, instead of posting that in comments... –  J. M. Jun 9 '13 at 4:43

1 Answer 1

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

share|improve this answer
    
+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. –  Michael E2 Jun 9 '13 at 5:40
    
@MichaelE2 Thanks and agree. I think there should be an alternative way which does not require manual specifying the number of grid nodes. –  Silvia Jun 9 '13 at 5:53
    
I like the use of Sign[], but maybe the PDE will look nicer if you use Piecewise[]. –  J. M. Jun 9 '13 at 20:26
    
@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. –  Silvia Jun 9 '13 at 20:36
    
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.) –  J. M. Jun 9 '13 at 20:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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