Skip to content

Choose a stop policy

A steady RANS case run to a fixed endTime usually spends its last third confirming what was already settled. The stop argument of submit_case and submit_sweep decides who ends it.

Policy Who stops it Use it for
none the case’s own endTime oscillating cases: near stall, sideslip, anything whose coefficients swing
watcher mcopenfoam, by lowering endTime while the solver runs steady external aerodynamics; the default for sweeps
solver OpenFOAM’s runTimeControl, injected at submit when the case must stop itself, with no server watching

submit_case defaults to none and submit_sweep to watcher.

Every few seconds the watcher reads postProcessing/coeffs/*/coefficient.dat. Once the run is past iteration 400 and has at least 10 samples in the trailing 200-iteration window, it checks each watched field:

  • Cd and Cl: the spread (max minus min) over the window must be under 0.3% of the window mean.
  • CmPitch: the spread must be under 0.0002, an absolute limit, because a moment’s mean can sit near zero.

When all of them pass, it sets endTime to the current iteration plus a margin, rounded up to the coefficient write interval. The watcher and early stopping explains why the rule looks like this.

Pass stop_policy with any field of the rule:

submit_case({
"case_path": "/cases/wing-a8",
"stop": "watcher",
"stop_policy": {
"rel_tol": 0.002,
"window": 300,
"min_iteration": 600,
"tail_iterations": 200,
"retime_function_objects": ["wallShearStress", "wallSurfaces"]
}
})

tail_iterations keeps the run going that many iterations past the point where it converged, and retime_function_objects moves those function objects’ timeStart so end-of-run samplers still cover the final window. Without it, a sampler set to start at iteration 800 never runs when the case stops at 620; the pre-flight check sampler_starts_after_stop warns about exactly this.

A point’s own stop overrides the job’s, so a polar can stop early on its steady points and run the stall points to full length:

submit_sweep({
"case_path": "/cases/flight-coarse",
"stop": "watcher",
"points": [{"alpha": 4}, {"alpha": 8}, {"alpha": 11, "stop": "none"}, {"alpha": 14, "stop": "none"}]
})

set_end_time(job_id, end_time) changes endTime on a running job; OpenFOAM reads it through runTimeModifiable. Lowering it to the current iteration or below ends the run at the next time step. Fields are written at that point only if the new value is a multiple of the case’s write interval.