From 3d2cea03679e899d71534b38e7a5737ddcb89b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Lleal=20Sirvent?= Date: Mon, 23 Feb 2026 11:47:59 +0100 Subject: [PATCH 1/3] Fix: prevent duplicate exports by popping matched time in is_it_time_to_export This updates `is_it_time_to_export` so that when a timestep matches a desired export time (within the `np.isclose` tolerances), the corresponding entry in `times` is popped. Previously, multiple consecutive timesteps within the tolerance window could all trigger `True`, leading to repeated exports for the same target time, especially at high simulation times where the relative tolerance (rtol) allows larger absolute differences. With this change: - only the first matching timestep triggers an export - the matched time is removed, preventing any subsequent exports for it This ensures a 1-to-1 mapping between requested and actual exports, provided the simulation reaches timesteps sufficiently close to the target times. --- src/festim/helpers.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/festim/helpers.py b/src/festim/helpers.py index 53e2cf700..c0bb6f2c6 100644 --- a/src/festim/helpers.py +++ b/src/festim/helpers.py @@ -324,7 +324,11 @@ def is_it_time_to_export( ) -> bool: """ Checks if the exported field should be written to a file or not based on the - current time and the times in `export.times` + current time and the times in `export.times' + + After a successful match, the corresponding time is removed from the list to + prevent multiple exports for the same target time. + Args: current_time: the current simulation time @@ -337,14 +341,16 @@ def is_it_time_to_export( """ if times is None: return True - - for time in times: + + for i, time in enumerate(times): if np.isclose(time, current_time, atol=atol, rtol=rtol): + times.pop(i) # consume the time so it is not exported again return True return False + _residual0 = 0 _prev_xnorm = 0 From e22bd56bb61704ecc8a50f32c8bb158dfd3b2c6b Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Mon, 23 Feb 2026 09:21:10 -0500 Subject: [PATCH 2/3] ruff formatting --- src/festim/helpers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/festim/helpers.py b/src/festim/helpers.py index c0bb6f2c6..47025048b 100644 --- a/src/festim/helpers.py +++ b/src/festim/helpers.py @@ -325,7 +325,7 @@ def is_it_time_to_export( """ Checks if the exported field should be written to a file or not based on the current time and the times in `export.times' - + After a successful match, the corresponding time is removed from the list to prevent multiple exports for the same target time. @@ -341,7 +341,7 @@ def is_it_time_to_export( """ if times is None: return True - + for i, time in enumerate(times): if np.isclose(time, current_time, atol=atol, rtol=rtol): times.pop(i) # consume the time so it is not exported again @@ -350,7 +350,6 @@ def is_it_time_to_export( return False - _residual0 = 0 _prev_xnorm = 0 From 74c28a67220509a807c9ca071acb5a015b3e83ea Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Mon, 23 Feb 2026 09:25:31 -0500 Subject: [PATCH 3/3] make a copy of times as attributes --- src/festim/exports/profile_1d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/festim/exports/profile_1d.py b/src/festim/exports/profile_1d.py index 670e9a527..ccc2feefb 100644 --- a/src/festim/exports/profile_1d.py +++ b/src/festim/exports/profile_1d.py @@ -45,7 +45,7 @@ def __init__( self.t = [] self.x = None self.subdomain = subdomain - self.times = times + self.times = times.copy() if times is not None else None self._dofs = None self._sort_coords = None