How to trigger WhenEvent for NDSolve in parallel?

Say I have a system of differential equations that I need to solve for different initial conditions and say the process is sufficiently expensive and I have sufficiently many that I am calculating in parallel. This system contains a WhenEvent.

As minimal example a model for a bouncing ball with different acceleration due to gravity.

state =
First@NDSolveProcessEquations[
{
y''[t] == #, y == 5,
y' == 0,
WhenEvent[y[t] == 0, y'[t] -> -0.95 y'[t]]
},
y, t,
Method -> {"StiffnessSwitching", "EquationSimplification" -> "Solve"}
] & /@ {-9.81, -5.5, -3.3};

This evaluates in serial without issue with the initial height being varied. Code below is setup for parallel processing.

resS = ConstantArray[Null, 3];
Do[
Module[{state1, r},
state1 =
NDSolveReinitialize[state[[i]], {y == i 10}] // First;
NDSolveIterate[state1, {0, 10}];
r = NDSolveProcessSolutions[state1];
resS[[i]] = r;
],
{i, 3}]
Plot[y[t] /. #, {t, 0, 10}] & /@ resS // GraphicsRow The affect of WhenEvent is seen with each bounce when y[t] == 0.

However in parallel the WhenEvent does not trigger.

resP = ConstantArray[Null, 3];
LaunchKernels[];
SetSharedVariable[resP];

ParallelDo[
Module[{state1, r},
state1 =
NDSolveReinitialize[state[[i]], {y == i 10}] // First;
NDSolveIterate[state1, {0, 10}];
r = NDSolveProcessSolutions[state1];
resP[[i]] = r;
],
{i, 3}]
Plot[y[t] /. #, {t, 0, 10}] & /@ resP // GraphicsRow WhenEvent never triggers and the ball falls through the floor forever.

Any ideas on how to trigger WhenEvent for NDSolve in parallel without reinventing the wheel?

• Seems that Parallel* is having trouble with NDSolveStateData. It's not even related to WhenEvent. A possible boiling down: state = First@ NDSolveProcessEquations[{y''[t] == #, y == 5, y' == 0}, y, t] &[-9.81]; resP = ParallelTable[ NDSolveIterate[state, {0, 10}]; NDSolveProcessSolutions[state], {1}]. DistributedContexts option doesn't seem to help. – xzczd Jan 3 at 17:50

Your code is complex. It's all easier

g = {-9.81, -5.5, -3.3}; y0 = {10, 20, 30};
ParallelTable[{sol =
NDSolve[{y''[t] == g[[i]], y == y0[[i]], y' == 0,
WhenEvent[y[t] == 0, y'[t] -> -0.95 y'[t]]}, y, {t, 0, 10}];
Plot[y[t] /. sol, {t, 0, 10}]}, {i, 3}] • I'm afraid this isn't what OP wants. Those NDSolveProcessEquations etc. cannot be circumvented. Notice this question is probably a follow-up of this question. – xzczd Jan 3 at 16:30
• @xzczd I do not know what OP wants, but he incorrectly uses parallel computing. – Alex Trounev Jan 3 at 16:45
• @xzczd You are correct that the above is not in line with what I am seeking. Keep in mind that the example is just a minimal example to demonstrate the issue. The real problem will have multiple NDSolveReinitialize calls per system. – Edmund Jan 3 at 17:26
• @AlexTrounev The actual system is sufficiently expensive such that there is a performance gain when utilizing the NDSolve* functions instead of NDSolve directly. – Edmund Jan 3 at 17:31
• @Edmund Are you sure there will be a time gain? – Alex Trounev Jan 3 at 18:22