From 56314f7c40f69b0ced325ef0dda21bb2e66fda91 Mon Sep 17 00:00:00 2001 From: Erik van Sebille Date: Tue, 30 Jul 2024 13:47:43 +0200 Subject: [PATCH 1/2] Stop execution when particleset is empty --- parcels/particleset.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/parcels/particleset.py b/parcels/particleset.py index 09010f650..26b1a9c8e 100644 --- a/parcels/particleset.py +++ b/parcels/particleset.py @@ -973,6 +973,10 @@ def execute(self, pyfunc=AdvectionRK4, pyfunc_inter=None, endtime=None, runtime= # End of interaction specific code time = next_time + # Check for empty ParticleSet + if np.isinf(next_prelease) and len(self) == 0: + return StatusCode.StopAllExecution + if abs(time - next_output) < tol or dt == 0: for fld in self.fieldset.get_fields(): if hasattr(fld, 'to_write') and fld.to_write: From f4fa1e9c75562794f795e4103aa3205099614350 Mon Sep 17 00:00:00 2001 From: Erik van Sebille Date: Tue, 30 Jul 2024 13:48:32 +0200 Subject: [PATCH 2/2] Skip Kernel execution when no particles need to be executed --- parcels/particleset.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/parcels/particleset.py b/parcels/particleset.py index 26b1a9c8e..1a410cf19 100644 --- a/parcels/particleset.py +++ b/parcels/particleset.py @@ -944,6 +944,11 @@ def execute(self, pyfunc=AdvectionRK4, pyfunc_inter=None, endtime=None, runtime= tol = 1e-12 while (time < endtime and dt > 0) or (time > endtime and dt < 0) or dt == 0: + # Check if we can fast-forward to the next time needed for the particles + if dt > 0: + skip_kernel = True if min(self.time) > (time + dt) else False + else: + skip_kernel = True if max(self.time) < (time + dt) else False time_at_startofloop = time if dt > 0: @@ -953,9 +958,10 @@ def execute(self, pyfunc=AdvectionRK4, pyfunc_inter=None, endtime=None, runtime= # If we don't perform interaction, only execute the normal kernel efficiently. if self.interaction_kernel is None: - res = self.kernel.execute(self, endtime=next_time, dt=dt) - if res == StatusCode.StopAllExecution: - return StatusCode.StopAllExecution + if not skip_kernel: + res = self.kernel.execute(self, endtime=next_time, dt=dt) + if res == StatusCode.StopAllExecution: + return StatusCode.StopAllExecution # Interaction: interleave the interaction and non-interaction kernel for each time step. # E.g. Normal -> Inter -> Normal -> Inter if endtime-time == 2*dt else: