Skip to content

[FEATURE] Clamp delta_time and format logs#216

Merged
camUrban merged 5 commits into
mainfrom
feature/formatting_and_delta_time_clamp
Jul 2, 2026
Merged

[FEATURE] Clamp delta_time and format logs#216
camUrban merged 5 commits into
mainfrom
feature/formatting_and_delta_time_clamp

Conversation

@camUrban

@camUrban camUrban commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Description

This PR standardizes numeric formatting across the log output and error messages, adds a format_duration helper for human-readable timing lines, and clamps the default delta_time estimate so that unsteady motions are always resolved with a minimum temporal fidelity. The formatting changes are cosmetic and do not affect any computed result. The delta_time clamp only lowers an estimate that was too coarse, so existing simulations that already met the resolution floor, or that pass an explicit delta_time, are unaffected.

Motivation

The solver, convergence, and trim logs mixed several ad hoc rounding styles (round(x, 2), np.round(x, 3), %g, %.2e), which produced inconsistent precision and hard-to-scan columns. A single three-significant-figure convention (with four significant figures reserved for the convergence metric percentages) makes the output uniform and easier to read. Separately, the analytical delta_time estimate matches wake and bound ring vortex chord lengths, which does not by itself guarantee the motion is sampled finely enough in time: a coarse chordwise discretization or a slow motion can leave the estimate too large to resolve the flapping cycle. Clamping to at least 30 time steps per LCM period guards against that failure mode without changing well-resolved cases.

Relevant Issues

None.

Changes

  • Added format_duration and its _DURATION_PAD_WIDTH constant to _functions.py, formatting a duration as hours, minutes, and seconds with three significant figures, optional left-padding for aligned log columns, and carry handling for a seconds remainder that rounds up to 60.
  • Clamped the analytical delta_time estimate in Movement.__init__ to at most _lcm_period / _MIN_TIME_STEPS_PER_LCM_PERIOD (30 steps per LCM period) for non-static movements, moving the local period computation ahead of the delta_time resolution block and updating the delta_time_type docstring.
  • Standardized numeric formatting to the #.3G specifier (and #.4G for the convergence metric percentages) across convergence.py, trim.py, output.py, _oscillation.py, _convergence_meshing.py, movements/movement.py, and geometry/airfoil.py, and switched the free flight sub-iteration log strings in problems.py to %#.3G; convergence timing lines now route through format_duration.
  • Added # type: ignore[attr-defined] with an explanatory comment to the two prange loops in _aerodynamics_functions.py to suppress mypy false positives arising from Numba's unannotated prange.__new__.
  • Added unit coverage for format_duration in tests/unit/test_functions.py and the delta_time clamp in tests/unit/test_movement.py, adjusted a scalar-rounding assertion in tests/integration/test_output.py, and regenerated the affected example logs, plots, and animations under docs/examples_expected_output/.

Dependency Updates

None.

Change Magnitude

Minor: Small change such as a bug fix, small enhancement, or documentation update.

Checklist (check each item when completed or not applicable)

  • I am familiar with the current contribution guidelines.
  • PR description links all relevant issues and follows this template.
  • My branch is based on main and is up to date with the upstream main branch.
  • All calculations use S.I. units.
  • Code is formatted with black (line length = 88).
  • Code is well documented with block comments where appropriate.
  • Any external code, algorithms, or equations used have been cited in comments or docstrings.
  • All new modules, classes, functions, and methods have docstrings in reStructuredText format, and are formatted using docformatter (--in-place --black). See the style guide for type hints and docstrings for more details.
  • All new classes, functions, and methods in the pterasoftware package use type hints. See the style guide for type hints and docstrings for more details.
  • If any major functionality was added or significantly changed, I have added or updated tests in the tests package.
  • Code locally passes all tests in the tests package.
  • This PR passes the ReadTheDocs build check (this runs automatically with the other workflows).
  • This PR passes the ascii-only, black, codespell, docformatter, isort, and pre-commit-hooks GitHub actions.
  • This PR passes the mypy GitHub action.
  • This PR passes all the tests GitHub actions.

camUrban added 5 commits July 2, 2026 10:56
The default delta_time estimate sizes the wake ring vortices to match
the bound trailing edge ring vortices, but that criterion alone does
not guarantee that the motion itself is adequately sampled: a coarse
chordwise discretization or a slow motion can produce a delta_time
spanning a large fraction of a motion cycle. Clamp the estimate for non
static Movements so that there are at least 30 time steps per LCM
period.

Explicit numeric delta_time values are never clamped, and while the
iterative "optimize" option is seeded with the clamped estimate, its
search remains deliberately unconstrained by the clamp. Move the period
property computation above the delta_time resolution in Movement's
initialization method, since the clamp reads the LCM period. Add unit
tests covering the clamped and unclamped paths.
Replace ad-hoc round() and str() calls throughout the logging, trim,
convergence, and output paths with G-format specifiers so that
displayed numbers carry a consistent number of significant figures
rather than a fixed decimal count. This keeps very small and very large
magnitudes readable instead of collapsing to zero or sprawling across
many digits.

Attach explicit unit labels (s, m/s, deg, N) to the state and result
messages so the logged values are unambiguous, and add spaces around
the equals signs for legibility.

Update the Reynolds number test regex to match the new
three-significant-figure uppercase scientific notation produced by the
alternate-form G specifier.
The convergence analysis logs report elapsed times in raw seconds,
which reads poorly once a study runs long: a multi-hour unsteady sweep
logs as tens of thousands of seconds. Add a format_duration helper to
_functions.py that renders a duration as hours, minutes, and
three-significant-figure seconds, dropping the leading units when they
are zero, collapsing to an hours-only form at 1000 hours, carrying a
seconds remainder that rounds to 60 into the minutes place, and placing
the sign of a negative duration on the largest unit.

Route the eight timing lines in convergence.py through the helper. They
use its unpadded default; an opt-in left_pad flag can instead
right-align the values of repeated log lines into a common column, with
the field width sized for the widest possible form, including a
three-digit float exponent in the seconds place.
@camUrban camUrban added maintenance Improvements or additions to documentation, testing, robustness, or tooling feature New feature or request labels Jul 2, 2026
@camUrban camUrban self-assigned this Jul 2, 2026
@camUrban camUrban requested a review from Copilot July 2, 2026 21:03
@camUrban camUrban added this to the v5.1.0 milestone Jul 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR standardizes numeric formatting in logs/error messages, adds a format_duration helper for human-readable timing output, and introduces a clamp on the default delta_time estimate to ensure a minimum temporal resolution for non-static unsteady motions.

Changes:

  • Added format_duration (with optional fixed-width padding) and updated convergence timing logs to use it.
  • Added a minimum-resolution clamp to the analytically-estimated delta_time in Movement.__init__, plus unit tests covering clamped/non-clamped cases.
  • Converted multiple log/error-message numeric formats to a consistent #. significant-figure style and regenerated expected example outputs.

Reviewed changes

Copilot reviewed 13 out of 65 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/unit/test_movement.py Adds unit tests for the delta_time clamp behavior (non-static vs static) and adjusts an existing mocked-value test.
tests/unit/test_functions.py Adds unit tests for format_duration, including rollover and left-padding behavior.
tests/integration/test_output.py Updates Reynolds-number log formatting assertion to match the new formatting convention.
pterasoftware/trim.py Standardizes trim-state logging numeric formatting and adds explicit units in the log message.
pterasoftware/problems.py Updates free-flight sub-iteration residual logging to consistent significant-figure formatting.
pterasoftware/output.py Standardizes numeric formatting in logged results and scalar-plot labels/colorbar formatting.
pterasoftware/movements/movement.py Introduces minimum time-steps-per-LCM-period clamp for analytical delta_time estimates and updates optimization logging formatting.
pterasoftware/geometry/airfoil.py Updates an airfoil normalization error message to the new formatting convention.
pterasoftware/convergence.py Routes convergence timing lines through format_duration and standardizes convergence metric formatting.
pterasoftware/_oscillation.py Standardizes validation error message formatting for custom spacing functions.
pterasoftware/_functions.py Adds format_duration and _DURATION_PAD_WIDTH to centralize duration formatting for logs.
pterasoftware/_convergence_meshing.py Standardizes delta_time cache/optimization log formatting.
pterasoftware/_aerodynamics_functions.py Adds targeted mypy ignores for prange false positives with an explanatory comment.
docs/examples_expected_output/unsteady_static_convergence/example_convergence.log Regenerates expected log output to reflect new numeric and duration formatting.
docs/examples_expected_output/unsteady_ring_vortex_lattice_method_solver_static/example_solver.log Regenerates expected log output to reflect new numeric formatting.
docs/examples_expected_output/unsteady_ring_vortex_lattice_method_solver_static_ground_effect/example_solver.log Regenerates expected log output to reflect new numeric formatting.
docs/examples_expected_output/steady_ring_vortex_lattice_method_solver/example_solver.log Regenerates expected log output to reflect new numeric formatting (including Reynolds number).
docs/examples_expected_output/steady_ring_vortex_lattice_method_solver_non_trapezoidal/example_solver.log Regenerates expected log output to reflect new numeric formatting (including Reynolds number).
docs/examples_expected_output/steady_horseshoe_vortex_lattice_method_solver/example_solver.log Regenerates expected log output to reflect new numeric formatting (including Reynolds number).
docs/examples_expected_output/steady_convergence/example_convergence.log Regenerates expected convergence log output to reflect new duration/metric formatting.
docs/examples_expected_output/free_flight_unsteady_ring_vortex_lattice_method_solver_glider/example_solver.log Regenerates expected free-flight log output to reflect new numeric/time formatting.
docs/examples_expected_output/free_flight_unsteady_ring_vortex_lattice_method_solver_flapping/example_solver.log Regenerates expected free-flight log output to reflect new numeric/time formatting.
docs/examples_expected_output/analyze_unsteady_trim/example_trim.log Regenerates expected trim log output to reflect new numeric formatting and units in state logs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pterasoftware/movements/movement.py
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.57143% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.72%. Comparing base (c82ef5f) to head (ccb54d8).

Files with missing lines Patch % Lines
pterasoftware/trim.py 50.00% 5 Missing ⚠️
pterasoftware/movements/movement.py 86.36% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #216      +/-   ##
==========================================
+ Coverage   93.69%   93.72%   +0.02%     
==========================================
  Files          44       44              
  Lines        8473     8504      +31     
==========================================
+ Hits         7939     7970      +31     
  Misses        534      534              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@camUrban camUrban merged commit d5ee676 into main Jul 2, 2026
39 checks passed
@camUrban camUrban deleted the feature/formatting_and_delta_time_clamp branch July 2, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request maintenance Improvements or additions to documentation, testing, robustness, or tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants