1
$\begingroup$

I try to solve a partial differential equation by NDSolve. At some point, I want to stop the integrating by a condition that compares the min value of the function with a threshold. I tried to use StopIntegration in the WhenEvent, and tried using NMinimize to find the min value of the function. But it does not seem stop the evaluation. From the warning message, I think the conditions of NMinimize[h[x, t], {x, t}] <= 0.01 I set for whenevent may be wrong. Could someone explain to me what is going on? How could I handle this problem? Is there any better or simpler way to do that?

mdfun = First[h /. NDSolve[{D[h[x, t], t] + D[h[x, t]^-1*D[h[x, t], x], x] + 
   D[h[x, t]^3*D[h[x, t], {x, 3}], x] == 0, 
 h[0, t] == h[2 Sqrt[2] \[Pi], t], 
 h[x, 0] == 1 + 1/10*Sin[x/Sqrt[2]], 
 WhenEvent[NMinimize[h[x, t], {x, t}] <= 0.01, 
  "StopIntegration"]}, h, {x, 0, 2 Sqrt[2] \[Pi]}, {t, 0, 10}, 
StepMonitor :> Print[t]]]
$\endgroup$

1 Answer 1

6
$\begingroup$

Ok, at first you don't solve your equation properly, the grid spacing is not enough for the entire time range. So first increase resolution, e.g.:

tmax = 10;
mdfun = NDSolveValue[
  {D[h[x, t], t] + D[h[x, t]^-1*D[h[x, t], x], x] + D[h[x, t]^3*D[h[x, t], {x, 3}], x] == 0,
   h[0, t] == h[2 Sqrt[2] \[Pi], t], h[x, 0] == 1 + 1/10*Sin[x/Sqrt[2]]},
   h, {x, 0, 2 Sqrt[2] \[Pi]}, {t, 0, tmax},
   AccuracyGoal -> 2, PrecisionGoal -> 2,
   Method -> {"MethodOfLines", "SpatialDiscretization" -> {"TensorProductGrid", 
     "MinPoints" -> 3000, "MaxPoints" -> 3000}}];

Then you can get nice solution:

Plot[mdfun[x, #] & /@ Range[0, tmax, 1] // Evaluate, {x, 0, 2 Sqrt[2] \[Pi]},
  PlotRange -> {0, 1.5}, PlotStyle -> Opacity /@ (Range[0, tmax, 1]/tmax)]

enter image description here

now you see that the event h<0.01 is never achived.

Secondly, NMinimize returns value in form {value, {x,y}}, so you should use NMinimize[..][[1]]. The other point you should properly specify the range of your variables for NMinimize like this (.6 - just some arb. limit):

NMinimize[{mdfun[a, b], 0 < a < 2 Sqrt[2] \[Pi], 0 < b < t}, {a, b}][[1]] < .6

Now the whole thing works, but very slow. I would suggest to make condition simply for point, where the min is located. find the minimum with previus solution:

xmin = x /. Minimize[{mdfun[x, t], 0 < x < 2 Sqrt[2] \[Pi], 0 < t < tmax}, {x, t}][[2]]

and rewrite whenevent:

WhenEvent[h[xmin, t] < .4, "StopIntegration"]

Then it will work much faster.

$\endgroup$
4
  • $\begingroup$ Hi,@funnypony! I adopted your suggestions except for grid spacing for faster here I set it is 300. I do think your advice is correct. Actually, I don't know the exact position where the min-value is located, the eqn. in my post just makes the issue simpler. Thus, I still use WhenEvent with NMinimize. But when I run it, MMA spits a stack of warning message. However, it still returns a result, when I plot it, I find WhenEvent doesn't work because the solution contains obviously value which is less than 0.6. Pls see the following code :) $\endgroup$
    – Enter
    Commented Oct 19, 2014 at 15:18
  • $\begingroup$ tmax = 10; mdfun = First[ h /. NDSolve[{D[h[x, t], t] + D[h[x, t]^-1*D[h[x, t], x], x] + D[h[x, t]^3*D[h[x, t], {x, 3}], x] == 0, h[0, t] == h[2 Sqrt[2] \[Pi], t], h[x, 0] == 1 + 1/10*Sin[x/Sqrt[2]], WhenEvent[ NMinimize[{mdfun[x, t], 0 < x < 2 Sqrt[2] \[Pi], 0 < t < tmax}, {x, t}][[1]] < 0.6, "StopIntegration"]}, h, {x, 0, 2 Sqrt[2] \[Pi]}, {t, 0, tmax}, AccuracyGoal -> 2, PrecisionGoal -> 2, Method -> {"MethodOfLines", "SpatialDiscretization" -> {"TensorProductGrid", "MinPoints" -> 300, "MaxPoints" -> 300}}]] $\endgroup$
    – Enter
    Commented Oct 19, 2014 at 15:20
  • $\begingroup$ lxy, please look once again how i wrote whenevent - with a and b instead of x and t. x and t are ndsolve variables and better avoid inserting them in numerical functions. The other point - you search for min at each integration step, so at any time the boundary for this variable is not tmax but t. write it this way: NMinimize[{mdfun[a, b], 0 < a < 2 Sqrt[2] [Pi], 0 < b < t}, {a, b}][[1]] < .6 and it will work, but slow.. $\endgroup$
    – funnyp0ny
    Commented Oct 19, 2014 at 18:12
  • $\begingroup$ Thanks @funnypony, it does work now. Thanks for your helpful suggestions! $\endgroup$
    – Enter
    Commented Oct 20, 2014 at 6: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.