Repository navigation
Conversation
Collaborator
Author
|
LOOK AT THE CI FLY. ALSO AS GOOD AS MY PIDGEOT WITH HM FLY |
Avoid repeated expensive recomputation in the level populations calculation while keeping the output bit-identical: - Cache the Ion instances returned by next_ion()/previous_ion() for internal use so that rate matrices of the recombining ion are only computed once rather than on every density iteration. - Cache the density-independent sum of the two-ion rate matrices. - Memoize plasmapy atomic_number/atomic_symbol/element_name lookups, which construct an expensive Particle object on every call. - Share the proton-electron ratio with the next ion since it only depends on temperature and the abundance/ionization datasets. Benchmark (21 temperatures x 9 densities): Fe XXIII 73.5->7.2 s, Ca XVIII 74.3->8.1 s, O VI 73.3->9.3 s, Fe XII (single-ion model) 9.9->5.0 s, coupled n-T 14.5->3.0 s.
Further speed up of the level populations calculation (and anything else that creates many Ion instances or reads many datasets), again keeping the output bit-identical: - DataIndexerHDF5.__getitem__ now does the membership check, child indexer creation, and read with a single open of the HDF5 file instead of two to three opens per access. - Memoize the set of available ion names and the database fiasco version per database file, keyed on the file modification time and size so that rebuilding the database invalidates the cache. This avoids re-reading the full ion index on every Ion instantiation. Ion instantiation drops from ~3.7 ms to ~1.9 ms and fiasco.proton_electron_ratio from ~2.1 s to ~1.5 s. O VI level populations (21 T x 9 n): 9.3 -> 8.1 s, dominated by np.linalg.solve.
Rather than constructing an Element instance (and thus an Ion instance for every ionization stage) of every element just to read the tabulated ionization fraction data, read the ioneq data directly from the database and instantiate only the first ion of each element to resolve the abundance exactly as before. The iteration order, arithmetic, warning messages, and missing-dataset behavior are unchanged such that the result is bit-identical, including on databases with missing ionization fraction datasets. Also use the memoized atomic number/symbol lookups in list_elements, list_ions, get_isoelectronic_sequence, and Element. fiasco.proton_electron_ratio drops from ~1.4 s to ~0.4 s. O VI level populations (21 T x 9 n): 8.1 -> 6.9 s. The full test suite also runs roughly twice as fast.
Refresh adjacent ions after changing proton/electron ratios or ionization fractions. Resolve database paths before caching metadata and distinguish atomic-number input types. Add numerical and cache-isolation regression tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Calls to
level_populationswith multiple densities repeatedly create adjacent ions and rebuild their rate matrices. This PR reuses those ions and the summed two-ion rate coefficients across density values. It also reduces HDF5 opens and caches database metadata and atomic lookups.The caches preserve public setter behavior: changing an ion's proton/electron ratio or ionization fraction refreshes its adjacent ions. Resolved database paths avoid cache collisions across directories, and typed atomic-number caching preserves input validation.
These measurements compare
a7e8ccbwithupstream/mainat668833a, which already includes the proton/electron-ratio improvements from #471. They replace the earlier measurements against the older baseline.proton_electron_ratioMedians of three timed calls after one warm-up per case, using the full CHIANTI 11.0.2 database on an AMD Ryzen 9 9950X with one linear-algebra thread. Every timed population calculation constructs a fresh
Ion; construction is included. Database/module caches remain warm. All six benchmark outputs are bit-for-bit identical to upstream.Temperature: 21 logarithmically spaced points from 10^5.5 to 10^7.5 K. Density: nine points from 10^8 to 10^12 cm^-3. The coupled case uses
density = 1e15 K cm^-3 / temperatureand the two-ion model.Both versions used Python 3.14.5, NumPy 2.4.6, SciPy 1.17.0, Astropy 8.1.0.dev684+g2b5b20b6d, h5py 3.16.0, and PlasmaPy 2026.2.0.
Validation: 63 focused tests pass, including numerical regression tests for setter changes and tests for database-cache isolation and input validation. Changed files pass Ruff.
Reproduce the timing comparison
Run the following on each checkout with the same full CHIANTI database configured and
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1: