Skip to content

Feature/Improve the speed and accuracy of finding the ideal time step size#97

Draft
camUrban wants to merge 6 commits intomainfrom
feature/optimize_delta_time_improvements
Draft

Feature/Improve the speed and accuracy of finding the ideal time step size#97
camUrban wants to merge 6 commits intomainfrom
feature/optimize_delta_time_improvements

Conversation

@camUrban
Copy link
Owner

@camUrban camUrban commented Feb 4, 2026

Description

When using Movement's delta_time="optimize" flag, Ptera Software has previously attempted to find the optimal time step size that minimizes the difference in areas between the trailing-edge bound RingVortices and the wake RingVortices they shed. This works well for small Strouhal-number-experiments. However, I've noticed serious issues in finding an appropriate time step for simulations with high Strouhal numbers.

Motivation

Finding a good time step value is critical to running unsteady simulations and assessing the convergence of their simulation parameters.

Relevant Issues

None.

Changes

  • Added the min_period property to Movement (along with caching and unit tests)
  • Refactored Movement's private LCM methods to private functions
  • Implemented _analytically_optimize_delta_time: fast analytical estimation of ideal delta_time by measuring wake displacement across a temporary Movement/UnsteadyProblem, including heuristics and warnings for low temporal resolution.
  • Changed Movement.delta_time handling: default (None) now runs the analytical estimator; delta_time="optimize" runs the analytical estimator first then calls the iterative _optimize_delta_time using the analytical result as the initial guess.
  • Adjusted iterative optimizer search bounds from sqrt(10) factor to +/- factor of 2.
  • Separated static and dynamic delta_time optimization:
    • _optimize_delta_time now detects static vs non-static Movements and delegates to two helpers: _optimize_delta_time_static (uses scipy.optimize.minimize_scalar with early cutoff) and _optimize_delta_time_non_static (brute-force search over integer num_steps_per_lcm_cycle so delta_time cleanly divides the LCM period).
    • Added logging and warnings when the best integer step count sits on search bounds.
  • Updated and expanded unit tests to cover analytical optimizer behavior, LCM functions, and adjust mocks/expectations accordingly.
  • Switched from a sample-mean-based approach to using the trapezoid rule for calculating the final-cycle-mean and final-cycle-RMS loads and load coefficients. For cases where the LCM period is an integer multiple of the time step, sample-based and trapezoid-rule-based means are identical. However, this fix improves robustness if the the LCM period isn't an integer multiple of the time step.
  • Updated PyCharm's "to inspect" inspection scope.

New Dependencies

None.

Change Magnitude

Moderate: Medium-sized change that adds or modifies a feature without large-scale impact.


Checklist

  • I am familiar with the current contribution guidelines.
  • 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.
  • After pushing, PR passes all automated checks (codespell, black, mypy, and tests).
  • PR description links all relevant issues and follows this template.

…cycle mean and RMS loads and coefficients

Assuming that the LCM period is an integer multiple of the time step, sample-based and trapezoid-rule-based means are identical. However, this fix improves robustness if the the LCM period isn't an integer multiple of the time step.
@camUrban camUrban self-assigned this Feb 4, 2026
@camUrban camUrban added bug Something isn't working feature New feature or request labels Feb 4, 2026
@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 93.85475% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.16%. Comparing base (e49d1df) to head (3116982).

Files with missing lines Patch % Lines
pterasoftware/movements/movement.py 93.82% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #97      +/-   ##
==========================================
- Coverage   91.32%   91.16%   -0.16%     
==========================================
  Files          32       32              
  Lines        5818     5968     +150     
==========================================
+ Hits         5313     5441     +128     
- Misses        505      527      +22     

☔ View full report in Codecov by Sentry.
📢 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.

Introduce an analytical delta_time estimator and refactor LCM helpers; add min_period caching and update optimization flow.

- Add module-level _lcm and _lcm_multiple functions and import numpy and problems.
- Implement _analytically_optimize_delta_time: fast analytical estimation of delta_time by measuring wake displacement across a temporary Movement/UnsteadyProblem; includes heuristics and warnings for low temporal resolution.
- Change Movement.delta_time handling: default (None) now runs the analytical estimator; delta_time="optimize" runs the analytical estimator first then calls the iterative _optimize_delta_time using the analytical result as the initial guess. Track this with _should_iteratively_optimize_delta_time.
- Add Movement.min_period property with caching (_min_period) returning the shortest non-zero motion period.
- Adjust iterative optimizer search bounds from sqrt(10) factor to +/- factor of 2.
- Update and expand unit tests to cover min_period, analytical optimizer behavior, LCM functions, and adjust mocks/expectations accordingly.
Refactor _optimize_delta_time to detect static vs non-static movements and delegate to two helpers: _optimize_delta_time_static (uses scipy.optimize.minimize_scalar with early cutoff) and _optimize_delta_time_non_static (brute-force search over integer num_steps_per_lcm_cycle so delta_time cleanly divides the LCM period). Adds logging and warnings when the best integer step count sits on search bounds. Updates unit test to use a larger initial_delta_time for the non-static case and to assert the new integer-step-based bounds instead of the previous [initial/2, initial*2] continuous bounds.
@camUrban camUrban changed the title Feature/Improve the speed and accuracy of finding the idea time step size Feature/Improve the speed and accuracy of finding the ideal time step size Feb 5, 2026
Expand unit test coverage for the movements module: add tests for optimizing delta_time (static and non-static), analytic optimization edge cases, LCM handling, and wake-area mismatch. New test classes validate dispatching behavior, warnings at optimization bounds (mocking optimizer/mismatch), temporal resolution warnings, and properties when OperatingPointMovement has a period. Also add tests for Movement-generated attributes (airplanes/operating_points) and many deepcopy/independence checks. Minor docstring wording tweaks and small fixture whitespace fixes.
Add two new command documents to manage test fixtures and redundancy (check-unit-tests-redundancy.md, delete-unused-fixtures.md). Refine existing test workflow docs (debug-unit-tests-and-fixtures.md, make-unit-tests-and-fixtures.md): standardize `$ARGUMENTS` formatting, clarify descriptions and steps, include guidance to run black after modifying files, improve examples and checklists, and remove minor formatting/emoji artifacts. These changes improve guidance for creating, debugging, and cleaning up unit tests and fixtures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant