# Outputs occurring at incorrect intervals when the timestep is high-precision

**URL:** https://pyfr.discourse.group/t/outputs-occurring-at-incorrect-intervals-when-the-timestep-is-high-precision/1341
**Category:** Bugs
**Created:** [21 February 2026 13:41 UTC](https://pyfr.discourse.group/t/outputs-occurring-at-incorrect-intervals-when-the-timestep-is-high-precision/1341 "2026-02-21T13:41:56Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![second\_moment](https://avatars.discourse-cdn.com/v4/letter/s/c57346/32.png) [@second\_moment](https://pyfr.discourse.group/u/second_moment)
#### Post date: [21 February 2026 13:41 UTC](https://pyfr.discourse.group/t/outputs-occurring-at-incorrect-intervals-when-the-timestep-is-high-precision/1341/1 "2026-02-21T13:41:56Z")

</div>

# Nature of bug

When I set the timestep to be a high-precision number (dt = 0.042735042735042736, pseudo-dt = 0.004273504273504274) and run the simulation for a long-enough time (tend = 1000.0), eventually the times when the .pyfrs files are dumped stop being multiples of dt\_out (in this case dt\_out = 5.0). In the error log below, the issue first occurs at time 520.04, with the distance to the nearest multiple of dt\_out growing from there. Note that dt\_out / dt = 117.0 in double precision.

Here are links to the [.ini file](https://drive.google.com/file/d/1MM685p_eoXOaB2VUg4hdDBm4zsW5SK9Q/view?usp=drive_link) and to the [.pyfrm file](https://drive.google.com/file/d/16JlER4ev1KYLg_tt4Bn4NdNARmmCcXlq/view?usp=drive_link) (although this does not seem to depend on the latter). Restarting at the last timestep that was still a multiple of dt\_out does not fix the issue.

# Error print out (if applicable)

```auto
root@2e3ab1618ab8:/workspace/bug# pyfr run -b cuda mesh.pyfrm inc-flow.ini
root@2e3ab1618ab8:/workspace/bug# ls -l inc-flow-5*.pyfrs
-rw-r--r-- 1 root root 801672 Feb 20 01:10 inc-flow-5.00.pyfrs
-rw-r--r-- 1 root root 801679 Feb 20 01:11 inc-flow-50.00.pyfrs
-rw-r--r-- 1 root root 801685 Feb 20 01:24 inc-flow-500.00.pyfrs
-rw-r--r-- 1 root root 801685 Feb 20 01:24 inc-flow-505.00.pyfrs
-rw-r--r-- 1 root root 801685 Feb 20 01:24 inc-flow-510.00.pyfrs
-rw-r--r-- 1 root root 801683 Feb 20 01:25 inc-flow-515.00.pyfrs
-rw-r--r-- 1 root root 801685 Feb 20 01:25 inc-flow-520.04.pyfrs
-rw-r--r-- 1 root root 801684 Feb 20 01:25 inc-flow-525.09.pyfrs
-rw-r--r-- 1 root root 801684 Feb 20 01:25 inc-flow-530.13.pyfrs
-rw-r--r-- 1 root root 801684 Feb 20 01:25 inc-flow-535.17.pyfrs
-rw-r--r-- 1 root root 801683 Feb 20 01:25 inc-flow-540.21.pyfrs
-rw-r--r-- 1 root root 801684 Feb 20 01:25 inc-flow-545.26.pyfrs
-rw-r--r-- 1 root root 801679 Feb 20 01:11 inc-flow-55.00.pyfrs
-rw-r--r-- 1 root root 801685 Feb 20 01:26 inc-flow-550.30.pyfrs
-rw-r--r-- 1 root root 801684 Feb 20 01:26 inc-flow-555.34.pyfrs
-rw-r--r-- 1 root root 801686 Feb 20 01:26 inc-flow-560.38.pyfrs
-rw-r--r-- 1 root root 801686 Feb 20 01:26 inc-flow-565.43.pyfrs
-rw-r--r-- 1 root root 801685 Feb 20 01:26 inc-flow-570.47.pyfrs
-rw-r--r-- 1 root root 801686 Feb 20 01:26 inc-flow-575.51.pyfrs
-rw-r--r-- 1 root root 801685 Feb 20 01:26 inc-flow-580.56.pyfrs
-rw-r--r-- 1 root root 801684 Feb 20 01:27 inc-flow-585.60.pyfrs
-rw-r--r-- 1 root root 801687 Feb 20 01:27 inc-flow-590.64.pyfrs
-rw-r--r-- 1 root root 801686 Feb 20 01:27 inc-flow-595.68.pyfrs

```

# PyFR information

- PyFR version: 2.1
- OS: Ubuntu 22.04
- Compiler and version: GNU Make 4.3
- Backend (if applicable): CUDA 12.2

---

<div class="post-metadata">

### Author: ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)
#### Post date: [21 February 2026 15:19 UTC](https://pyfr.discourse.group/t/outputs-occurring-at-incorrect-intervals-when-the-timestep-is-high-precision/1341/2 "2026-02-21T15:19:59Z")

</div>

This is mostly expected behaviour. PyFR aims to hit the first time t _after_ the time requested by the plugin. For a plugin time of t = 545.0 this happens to be 545.0427350427318. This is an unfortunate consequence of double precision arithmetic and the fact that with dual-time there is currently no support for changing dt to exactly hit plugin times (although there is a long standing PR for this, see [Support for variable time stepping by sambitmishra98 · Pull Request #495 · PyFR/PyFR · GitHub](https://github.com/PyFR/PyFR/pull/495)).

Regards, Freddie.

---

<div class="post-metadata">

### Author: ![second\_moment](https://avatars.discourse-cdn.com/v4/letter/s/c57346/32.png) [@second\_moment](https://pyfr.discourse.group/u/second_moment)
#### Post date: [22 February 2026 17:42 UTC](https://pyfr.discourse.group/t/outputs-occurring-at-incorrect-intervals-when-the-timestep-is-high-precision/1341/3 "2026-02-22T17:42:29Z")

</div>

Got it, thanks. For my purposes (fixed high-precision `dt`) I’ve added a check before running to warn if this issue arises before `tend`. In case it’s useful for others, here is what I’m using:

```auto
def actual_dt_out_matches_expected(tstart, tend, dt, dt_out, dt_min=1e-12, rounding=2):

    expected = []
    tcurr = tstart
    while tcurr <= tend:
        expected.append(tcurr)
        tcurr += dt_out

    actual = [tstart]
    tcurr = tstart
    tout_last = tstart
    tol = 5 * dt_min
    while tcurr <= tend:
        tcurr += dt
        if tcurr - tout_last >= dt_out - tol:
            actual.append(tcurr)
            tout_last = tcurr

    return expected == [round(t, rounding) for t in actual]

```

---

<div class="post-metadata">

### Author: ![fdw](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@fdw](https://pyfr.discourse.group/u/fdw)
#### Post date: [22 February 2026 19:51 UTC](https://pyfr.discourse.group/t/outputs-occurring-at-incorrect-intervals-when-the-timestep-is-high-precision/1341/4 "2026-02-22T19:51:30Z")

</div>

I’ll look into using Kahan summation for the next major release.

Regards, Freddie.
