Skip to content

peclet-flow 1.3.0

Choose a tag to compare

@eajfpeters eajfpeters released this 04 Oct 01:58
· 389 commits to main since this release

peclet-flow 1.3.0

Added

  • peclet.flow.march_to_steady(solver, monitor, ...) marches a solver to its steady state and
    returns a MarchResult (converged, steps, accelerated_steps, reason, num_restarts,
    monitor). By default the march is Anderson-accelerated (type II, on the device, through core's
    AndersonCore); accelerate=False is the plain march with the same stop test. On a dense
    staggered bed (φ 0.6, N = 64) it certifies in 93 steps instead of 325, 3.4–3.9× less wall time.
    Staggered Solver, and SolverColocated with the 'ghost' scheme; configurations the
    accelerator cannot take (VoF, variable ρ/μ, moving scenes, cell forces, …) raise with the reason
    and point at accelerate=False.
  • diagnostics.set_pressure_bottom_solver('auto' | 'direct' | 'algebraic') (developer tier)
    selects the engine of the agglomerated pressure bottom.

Changed (named numerics changes)

  • On GPU backends the pressure multigrid's bottom is solved on the device ('auto', the
    default, selects 'direct' where eligible: single rank, a bottom of at most 8192 cells with at
    most 64 fluid components, solids allowed): an FP64 flexible CG to 1e-5, preconditioned by an
    FP32 block-tridiagonal direct factor refactored once per operator change, with no host transfer.
    It replaces the host GraphAMG bottom there. Bubble column on an RTX 5080: 42.6 → 36.1–37.4 ms
    per step; over 50 steps the fields differ from the GraphAMG bottom by at most 2.7e-14 (relative)
    with identical outer iterations on every step. Host backends and the distributed path keep
    GraphAMG and are bitwise unchanged; 'algebraic' restores the previous engine on a GPU.

Changed

  • A faster VoF step with identical results (bitwise on CUDA and host): the parabolic-fit
    curvature fallback runs one GPU team per target cell (core 1.3.2's pvFitTerm / pvFitAccum
    split), and the batched marker-block container's last tier runs on persistent warp teams
    (14.8 → 7.4 ms per call on the bubble column).

Deprecated

  • Solver.hydro_force_torque() is deprecated and warns: it is not the force on the bodies.
    It returns the reconstructed surface-traction integral, which under-reads the drag by ~30 % at
    every resolution (traction / reaction 0.685–0.730 over φ 0.008–0.45 and N 24–128; the central
    difference spans the wall, so the deficit is in the viscous part) and a spinning sphere's torque
    by 28–41 %. The force and torque on the bodies is hydro_force_torque_reaction() — the
    discrete momentum reaction, exactly conservative; its torque reads 1.019–1.027 of the exact
    periodic-array value at 6–12 cells per radius. The traction, with its pressure/viscous split,
    is diagnostics.hydro_force_torque_traction(). The old name returns the same array as before
    and raises a DeprecationWarning naming both; it goes at the next major release. A consistent
    traction (from the momentum operator's small-cell-robust wall reconstruction) is planned.

Fixed

  • hydro_force_torque() (the traction) applied the index → physical conversion twice under a
    physical domain: 0.019× the reaction at extent 1, 3e-8× at 7.3. Cell units were unaffected.
  • enable_vof_momentum together with the VoF marker-block container now raises (in either
    order). Momentum-consistent transport skips the step that advects the markers, so with both on
    every marker stayed frozen while the momentum moved.
  • Pinned to core v1.4.0.

Known limitations

  • march_to_steady's converged=True certifies stationarity at the given dt: the state passed
    the stop test on consecutive plain steps. It does not certify that a plain march from the initial
    state would reach it. Without advection (Stokes) the steady state is unique. With advection,
    above a flow instability (a wake past its Hopf point) Anderson can converge to an unstable
    steady branch that a time march would never show; check such cases with accelerate=False or by
    stepping on from the result. The stop test assumes no mode decays slower than slow_rate per
    step; where one does it under-reads the remainder (dense bed at rtol 1e-10: ~1.4e-8 from the
    steady state), so treat certificates below ~1e-8 on such geometries as approximate.
  • The pressure in sealed fluid pockets is arbitrary. Fluid cells that no open face connects to
    the rest of the flow are out of reach of the pressure projection, so their pressure level is
    undetermined (a dense sphere bed, φ 0.6 at N 64, has 126 such cells in 115 pockets). The force on
    each body and the permeability, from hydro_force_torque_reaction(), are unaffected: they move
    by at most 1e-7. The surface-traction diagnostic diagnostics.hydro_force_torque_traction() is
    affected: per-body forces by about 2e-4 of the force, and on the collocated grid the bed-total
    traction is biased as well. Averages of get_p() that include pocket cells shift by 1e-3 to 4e-3
    of the pressure range for each pressure range by which the pockets are offset. A pocket mask and
    a corrected traction are planned after this release.
  • In cell units, cell_centers() and an analytic scene disagree by half a cell. Without an
    extent, cell_centers() returns i + 1/2 (origin 0, spacing 1), while set_scene places cell
    (i, j, k)'s centre at (i, j, k). An SDF sampled on cell_centers() for set_solid and the same
    body given to set_scene are therefore offset by half a cell. With a physical domain (extent=)
    both use origin + (i + 1/2) h and agree. The docstrings now say so; unifying the cell-unit
    convention changes results and is deferred to 2.0.0.