Skip to content

Numpy 2 compatibility - #87

Merged
A-CGray merged 26 commits into
mainfrom
feature-numpy2-compat
Oct 27, 2026
Merged

A-CGray merged 26 commits into
mainfrom
feature-numpy2-compat

Conversation

@A-CGray

@A-CGray A-CGray commented Mar 21, 2026 •

Copy link
Copy Markdown
Member

Purpose

Makes openconcept compatible with numpy 2.4+

Type of change

What types of change is it?
Select the appropriate type(s) that describe this PR

  • - Bugfix (non-breaking change which fixes an issue)
  • - New feature (non-breaking change which adds functionality)
  • - Breaking change (non-backwards-compatible fix or feature)
  • - Code style update (formatting, renaming)
  • - Refactoring (no functional changes, no API changes)
  • - Documentation update
  • - Other (please describe)

Testing

Explain the steps needed to test the new code to verify that it does indeed address the issue and produce the expected behavior.

Checklist

Put an x in the boxes that apply.

  • I have run unit and regression tests which pass locally with my changes
  • I have added new tests that prove my fix is effective or that my feature works
  • I have added necessary documentation

A-CGray and others added 7 commits March 20, 2026 23:57
np.complex_ was removed in NumPy 2.0. np.complex128 is semantically
identical and available in all supported NumPy versions.

Also fixes a pre-existing bug in combine_split_comp.py where dtype=np.dtype
(the class itself) was passed instead of the local variable dtype.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NumPy 2.0 removed automatic coercion of 1-element arrays to Python
scalars, so math.cos/sin/sqrt no longer accept numpy array inputs.
Replace with np.cos/sin/sqrt which handle arrays natively.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…enMDAO 3.43

Small numerical differences (~3e-6 relative) in surge_margin (N3) and
battery SOC_final (HybridTwin) arise from library version changes and
are not correctness regressions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
During Newton solver warmup iterations, fltcond|Utrue can temporarily
go negative, making Re negative and causing log(negative) = NaN which
propagates through the Jacobian.

Fix: compute Re = U*L/visc_kin and apply abs(Re) for real-valued
arrays only, so complex-step derivative checking still propagates the
imaginary part correctly (for complex arrays, negate Re where real(Re)<0).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@A-CGray
A-CGray requested a review from a team as a code owner March 21, 2026 04:02
@A-CGray
A-CGray requested a review from sabakhshi March 21, 2026 04:02
@A-CGray
A-CGray marked this pull request as draft June 11, 2026 15:25
@jmarette

Copy link
Copy Markdown

Hi, thanks for working on this.

We ran into the numpy >=1.20, <2 cap in setup.py. It makes OpenConcept 1.2.6 incompatible with current AeroSandbox, which wants numpy >= 2.2.6. This PR looked like the fix so we tried it.

Tested at 10f644b on Python 3.12.13, with numpy 2.5.1, OpenMDAO 3.45.0 and AeroSandbox 4.2.10. Full suite from source, same result on three runs:

461 passed, 2 failed, 2 skipped, 48 errors.

The 48 errors are all ModuleNotFoundError: No module named 'openaerostruct', which we simply didn't install. Nothing to do with numpy.

The 2 failures are HybridTwinThermalTestCase::test_values_thermalhybridtwin and N3HybridTestCase::test_defaults. Both are value checks. We get -3.80263173e-05 where -3.80158704e-05 is expected, so roughly 2.7e-5 relative against a 1e-5 tolerance.

That one might be worth your attention. The branch already carries "Loosen test tolerances for minor numerical shifts with NumPy 2.x / OpenMDAO 3.43", and that commit puts the drift at about 3e-6. What we see is an order of magnitude larger. Our guess is that numpy moved again after you calibrated it.

The main thing we wanted to ask about is the history. These changes went into main on 2026-03-21 and were reverted the same day, by 9187a53 and 14b7176. Neither commit message says why, and there are no comments here.

Did you hit something concrete, or was it backed out so it could land through this PR instead? We'd rather not pin an unmerged branch if you already know something is wrong with it.

If it's the latter, happy to help. We can post the full test log, run other configurations, or send a PR for the tolerance calibration.

A-CGray and others added 7 commits August 6, 2026 12:14
np.trapz and np.ComplexWarning were removed in NumPy 2, and NumPy 2.5 no
longer allows assigning size-1 arrays to scalar array elements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Exclude mdot_coolant from the propulsion input promotion with glob
character classes and connect it explicitly, instead of listing every
ac|propulsion input by hand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use U * sign(U.real), which is |U| for real inputs and remains complex-step
safe, rather than branching on the input dtype.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SOC_final reference values were under-converged results whose last
digits depend on the Newton iteration path, which changed in OpenMDAO 3.43.
Use the tightly converged values with an absolute tolerance consistent with
the solver tolerance, and revert the earlier tolerance loosening (the N3
discrepancy came from stale local engine deck caches, not NumPy).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OpenAeroStruct 2.7.1 does not support NumPy 2. OAS 2.10 does, but it
evaluates B-splines of panel quantities (t/c, skin and spar thickness) at
panel centres, which changes the aerostructural results; with uniform
distributions the results are unchanged. Update the reference values,
make run_OAS set the panel t/c directly, and bump the oldest tested
versions to OpenMDAO 3.35 (required by OAS 2.10), NumPy 1.25 and SciPy
1.11. Install pyCycle from GitHub in the latest build because its NumPy 2
fixes are unreleased.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.06%. Comparing base (0d2adeb) to head (5e47f96).

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #87   +/-   ##
=======================================
  Coverage   82.05%   82.06%           
=======================================
  Files         103      103           
  Lines       10730    10733    +3     
=======================================
+ Hits         8805     8808    +3     
  Misses       1925     1925           

☔ 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.

With Python 3.11, installing pyCycle pulled in the latest OpenMDAO, which
requires NumPy 2 and silently replaced the oldest NumPy and SciPy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@A-CGray
A-CGray marked this pull request as ready for review October 27, 2026 14:30
A-CGray and others added 6 commits October 27, 2026 10:37
The glob character classes also excluded any other input starting with
"t" or "m". Promote everything with "ac|propulsion|*" and rename just
mdot_coolant with an explicit tuple, which takes precedence over the
wildcard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Promote each ac|propulsion input by its full name, leaving out only the
per-node mdot_coolant, rather than renaming it out of the ac| namespace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since OpenMDAO 3.35 every problem creates a <name>_out directory in the
working directory, so running the tests left hundreds of them in the
repo root. Point OPENMDAO_WORKDIR at a temporary directory for the
pytest session unless the user has already set it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OpenMDAO is now pinned when pyCycle is installed, so the later step that
reinstalled the oldest OpenMDAO had nothing left to do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Use a single Python setup step that picks the oldest or latest version
- Let pyCycle and the testing and docs extras install in one pip call,
  rather than installing pyCycle, NumPy, SciPy and OpenMDAO separately
- Drop the conda always_yes config, which the latest build never needed,
  and pass -y to the one conda install instead

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Give each dep-versions value its own versions through matrix include,
so the job names list the OS and the Python, NumPy, SciPy and OpenMDAO
versions instead of every version setting for both builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@A-CGray A-CGray changed the title Numpy 2 comatibility Numpy 2 compatibility Oct 27, 2026
A-CGray and others added 2 commits October 27, 2026 11:10
Writing outputs to a temporary directory broke the Windows build: the
temporary directory and the checkout are on different drives, and
OpenMDAO's inputs report calls os.path.relpath on its output file. The
reports are what create the <name>_out directories, so turn them off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@A-CGray

A-CGray commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

@sabakhshi can you post the details of the environment you're having test failures with?

@sabakhshi

Copy link
Copy Markdown
Contributor

@sabakhshi can you post the details of the environment you're having test failures with?

certifi==2026.10.23 charset-normalizer==3.5.2 contourpy==1.4.0 cycler==0.12.1 fonttools==4.68.0 idna==3.20 iniconfig==2.3.1 kiwisolver==1.5.1 matplotlib==3.11.2 networkx==3.7 numpy==2.5.4 -e git+ssh://git@github.com/OpenMDAO/pyCycle.git@ee7e16126a7a54b5fe35292c53b7eb4e9572620b#egg=om_pycycle -e git+ssh://git@github.com/sabakhshi/OpenAeroStruct.git@0a4d614f9494cbadaba4a6fa32a33d6e54e14f34#egg=openaerostruct -e git+ssh://git@github.com/mdolab/openconcept.git@5e47f965c6b34f3f7d8dd057b504a47896f7b16a#egg=openconcept openmdao==3.45.1 packaging==26.3 parameterized==0.9.0 pillow==13.0.0 pluggy==1.7.0 Pygments==2.21.0 pyparsing==3.3.3 pytest==9.1.1 python-dateutil==3.0.0 requests==2.34.2 scipy==1.18.1 six==1.17.0 tzdata==2026.5 urllib3==2.8.0

@A-CGray

A-CGray commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

@sabakhshi which python version?

@sabakhshi

Copy link
Copy Markdown
Contributor

@sabakhshi which python version?

3.12.3

@A-CGray

A-CGray commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

I cannot recreate the failure you're seeing. Here's the full list of commands I ran (in the root dir of openconcept):

pyenv install 3.12.3
pyenv virtualenv 3.12.3 openconceptTest
pyenv activate openconceptTest
pip install -e .[testing]
pip install git+https://github.com/OpenMDAO/pyCycle.git
pytest -v

@A-CGray
A-CGray merged commit 6351bf4 into main Oct 27, 2026
11 checks passed
@A-CGray
A-CGray deleted the feature-numpy2-compat branch October 27, 2026 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants