Message Boards Message Boards

What is the correct way to create an animation in parallel using NDSolve?

Posted 1 year ago

As the title says. For example, in the following code ParallelTable takes 23 minutes:

R = 
 Annulus[{-0.9`, -1.95`}, {1.6`, 6.5`}];
soln = NDSolveValue[
     {I*D[u[t, x, y], t] + Laplacian[u[t, x, y], {x, y}] == 
         NeumannValue[0, True], u[0, x, y] == 
         Exp[-((x - 2/3)^2 + (y - Pi/2)^2)]/Pi}, u, 
     {t, 0., 20.}, Element[{x, y}, R]]
imgs = ParallelTable[
  Plot3D[Abs[soln[t, x, y]], {x, y} \[Element] R, 
   PlotRange -> {0, 1/3}, PlotPoints -> 100], {t, 0, 15}];
ListAnimate[imgs]

while Table takes about 20 seconds. In a real situation, the animation must have many more frames, with dt = 0.1, for example. This question is duplicated here.

POSTED BY: Jonathan Aumann
3 Replies
Posted 1 year ago

You would think using ParallelTable would save time by distributing the computations over several kernels. I think Roland's method was faster because he used Evaluate[ ] around Abs[soln[#,x,y]. If you retry yours with Evaluate[Abs[soln[t,x,y]], I bet it will execute in less time than 4.78125 seconds. Using Evaluate[ ] often helps when a computation takes a very long time.

POSTED BY: Alan Horwitz

Hi Jonathan,

the correct way is

R = 
 Annulus[{-0.9`, -1.95`}, {1.6`, 6.5`}];
soln = NDSolveValue[
     {I*D[u[t, x, y], t] + Laplacian[u[t, x, y], {x, y}] == 
         NeumannValue[0, True], u[0, x, y] == 
         Exp[-((x - 2/3)^2 + (y - Pi/2)^2)]/Pi}, u, 
     {t, 0., 20.}, Element[{x, y}, R]]

In[50]:= Timing[
 img = Array[(Plot3D[
       Evaluate[Abs[soln[#, x, y]]], {x, y} \[Element] R] &), {16}, 
    0] ;]

Out[50]= {4.78125, Null}

Regards Roland

POSTED BY: Roland Franzius

Thanks for trying, but the issue remains unsolved. Evaluate has no effect in this case because the time-consuming function, NDSolve, is not being delayed until plotting, and replacing Array with ParallelArray multiplies the evaluation time by at least 6. This takes 4.67 seconds:

AbsoluteTiming[ img = Array[(Plot3D[ Evaluate[Abs[soln[#, x, y]]], {x, y} \[Element] R] &), {16}, 0];]

While this takes 27.6 seconds:

AbsoluteTiming[ img = ParallelArray[(Plot3D[ Evaluate[Abs[soln[#, x, y]]], {x, y} \[Element] R] &), {16}, 0];]

For serial, my evaluation times as a function of the number of plots is: {{10, 12.2379}, {15, 18.5765}, {20, 24.7349}, {25, 31.6992}, {30, 41.3019}, {35, 45.4878}, {40, 51.805}, {45, 57.9418}, {50, 65.3213}}

While for parallel, it is: {{10, 293.046}, {15, 458.709}, {20, 611.03}, {25, 725.197}, {30, 873.236}, {35, 1027.61}, {40, 1116.4}, {45, 1244.97}, {50, 1397.45}}

The problem appears to be with the implementation of Parallel*

POSTED BY: Jonathan Aumann
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract