Time integration¶
FluxCore distinguishes physical time from pseudo-time. Physical time advances the simulated system. Pseudo-time is the nonlinear work used to converge a steady state or the implicit equations inside one physical step.
Pseudo-time step methods¶
- class gradientdynamics.fluxcore.FixedPseudoTimeStep(*, value: float)¶
Use a fixed pseudo-time increment in seconds.
- value: float¶
- class gradientdynamics.fluxcore.CflPseudoTimeStep(*, cfl: float = 50.0, local: bool = True)¶
Choose pseudo-time increments from a requested Courant number.
- cfl: float¶
Requested pseudo-time Courant number.
- local: bool¶
Permit cell-local pseudo-time scales for steady convergence.
- class gradientdynamics.fluxcore.AdaptiveCfl(*, initial: float = 1.0, target: float = 100.0, ramp_steps: int = 500, growth_factor: float = 1.25, retreat_factor: float = 0.5, minimum: float = 0.1, maximum: float | None = None, recovery_window: int = 8)¶
Residual-aware pseudo-time CFL progression.
- initial: float¶
CFL used at the beginning of the solve or after a restart that lacks history.
- target: float¶
Production CFL earned after stable nonlinear progress.
- growth_factor: float¶
Largest allowed CFL increase over one successful control window.
- retreat_factor: float¶
CFL reduction applied when progress or stability checks fail.
Steady time controls¶
- class gradientdynamics.fluxcore.SteadyTimeControls(*, max_pseudo_steps: int = 2000, minimum_pseudo_steps: int = 100, pseudo_time_step: FixedPseudoTimeStep | CflPseudoTimeStep | AdaptiveCfl = AdaptiveCfl(), convergence: ConvergenceCriteria | None = None, output_schedule: OutputSchedule | None = None)¶
Pseudo-time advancement to a steady converged solution.
- max_pseudo_steps: int¶
Maximum nonlinear pseudo-iterations.
- minimum_pseudo_steps: int¶
Minimum iterations completed before convergence can terminate the run.
- pseudo_time_step: FixedPseudoTimeStep | CflPseudoTimeStep | AdaptiveCfl¶
Pseudo-time step selection and progression method.
Inner pseudo-time controls¶
- class gradientdynamics.fluxcore.PseudoTimeControls(*, maximum_steps: int = 100, minimum_steps: int = 3, residual_drop: float = 2.0, absolute_residual: float | None = None, step_method: FixedPseudoTimeStep | CflPseudoTimeStep | AdaptiveCfl = CflPseudoTimeStep(), chunk_size: int = 25, early_stop: bool = True, output_every: int | None = None)¶
Nonlinear convergence policy inside each physical-time step.
- maximum_steps: int¶
Maximum pseudo-iterations permitted for one physical step.
- minimum_steps: int¶
Minimum pseudo-iterations before early stopping is evaluated.
- residual_drop: float¶
Required orders of residual reduction within the physical step.
- absolute_residual: float | None¶
Optional absolute inner-convergence threshold.
- chunk_size: int¶
Number of pseudo-iterations executed between convergence, cancellation and live-output checks.
- output_every: int | None¶
Optional inner-history cadence in pseudo-iterations. Field and checkpoint cadences are configured with
OutputSchedule.
Physical time controls¶
- class gradientdynamics.fluxcore.PhysicalTimeControls(*, time_step: float, steps: int | None = None, end_time: float | None = None, order: int = 2, startup_steps: int = 1, predictor: str = 'extrapolate', inner: PseudoTimeControls = PseudoTimeControls(), statistics: StatisticsOutput | None = None, output_schedule: OutputSchedule | None = None)¶
Implicit physical-time advancement for URANS, DES and DDES simulations.
- time_step: float¶
Physical time increment in seconds.
- order: Literal[1, 2]¶
Requested physical-time accuracy order.
- startup_steps: int¶
Initial steps advanced with the startup time discretisation before the requested higher-order history is available.
- predictor: Literal['previous', 'extrapolate']¶
Initial field prediction for each new physical step.
- inner: PseudoTimeControls¶
Pseudo-time convergence policy applied inside every physical step.
Physical and pseudo-time example¶
from gradientdynamics.fluxcore import (
AdaptiveCfl,
OutputSchedule,
PhysicalTimeControls,
PseudoTimeControls,
)
time_controls = PhysicalTimeControls(
time_step=2.5e-5,
steps=12_000,
order=2,
startup_steps=1,
predictor="extrapolate",
inner=PseudoTimeControls(
maximum_steps=80,
minimum_steps=4,
residual_drop=2.5,
step_method=AdaptiveCfl(
initial=1.0,
target=75.0,
ramp_steps=40,
),
chunk_size=10,
early_stop=True,
output_every=5,
),
output_schedule=OutputSchedule(
history_every_pseudo_steps=5,
fields_every_physical_steps=20,
checkpoint_every_physical_steps=100,
),
)