I want to use WhenEvent with a PDE after it has reached steady state. I'm posting a system of 2 equations (my real system has 6) and I'm solving the advection-diffusion-reaction 2nd order PDE.
First I set up the PDE:
pde = {
D[p1[z, t], t] == Dif D[p1[z, t], z, z] - v D[p1[z, t], z] - kp1 p1[z, t],
D[p2[z, t], t] == Dif D[p2[z, t], z, z] - v D[p2[z, t], z] - kp2 p2[z, t] + kp1 p1[z, t]};
ic = {p1[z, 0] == p1in, p2[z, 0] == p2in};
bcs = {
v p1in == (v p1[z, t] - Dif D[p1[z, t], z] /. z -> 0), (D[p1[z, t],z] /. z -> l) == 0,
v p2in == (v p2[z, t] - Dif D[p2[z, t], z] /. z -> 0), (D[p2[z, t],z] /. z -> l) == 0
};
params = {Dif -> 0.01, v -> 2, l -> 15, cin1 -> 10, p1in -> 30, p2in -> 60, kp1 -> 0.1, kp2 -> 0.05};
soli =NDSolve[
{pde, ic, bcs} /. params, {p1[z, t], p2[z, t]}, {z, 0, 15}, {t, 0, 100}, Method -> {"MethodOfLines", "SpatialDiscretization" ->{"TensorProductGrid", "MinPoints" -> 750}}];
I want to use WhenEvent
to output the distance (i.e. z-variable
) it takes for p1[z,t]
(or p2[z,t]
) to reach a chosen value. Something along the lines of:
WhenEvent[{p1[z,t]==20}, Print[
distance along z]
My approach:
First I tried adding WhenEvent into soli
like this:
soli =NDSolve[{pde, ic, bcs, WhenEvent[{p1[z, t] == 20}, {Print[z]}]} /.
params, {p1[z, t], p2[z, t]}, {z, 0, 15}, {t, 0, 100}, Method -> {"MethodOfLines", "SpatialDiscretization" -> {"TensorProductGrid", "MinPoints" -> 750}}];
That gave me all sorts of errors. My question is how do I get it to print out the distance along z that it take for p1[z,t]
to decay to 20?
Attempt: Then I was wondering if I should discretize the solution so that I am working in 2D space instead of 3D space because it might be easier to extract the value? Something like:
ss = Table[Plot[p1[z, t] /. soli, {z, 0, 15}, PlotRange -> All], {t, 0, 10, .25}];
And then choose the last plot (i.e. so I'm pretty sure steady state is reached) with ss[[40]]
but then I'm not sure how to get the output from ss[[40]]
?
Part of me think I want to put it all into a module
? Thanks in advance.
p1[z, t] == 20
afterNDSolve
is done? Or is there some reason you want to detect it during integration? $\endgroup$Module
but I guess I could still do that by this approach too. Anyway, I was attempting to useSolve
just now but it's not working out. Would you mind showing me the string of code to solve forp1[z,t]==20
? $\endgroup$