Skip to content

refactor: replace Unitful with FlexUnits#165

Open
henry2004y wants to merge 1 commit into
masterfrom
refactor-flexunits
Open

refactor: replace Unitful with FlexUnits#165
henry2004y wants to merge 1 commit into
masterfrom
refactor-flexunits

Conversation

@henry2004y

Copy link
Copy Markdown
Owner

This is an experiment on switching from Unitful to FluxUnits.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request replaces the Unitful dependency with FlexUnits, updating the internal unit module to FlexUnitsBatsrus and adjusting documentation, examples, and extensions accordingly. Type constraints were also added to core data structures in src/type.jl. Feedback focuses on the new unit implementation, noting that changing physical constants from values to functions is a breaking change. Additionally, the reviewer recommended addressing performance issues related to Ref{Any} usage, removing redundant logic in getunit, and refactoring duplicated calculations for the Rydberg constant.

Comment on lines +17 to +24
me() = _me[]
mp() = _mp[]
q() = _q[]
k() = _k[]
μ0() = _μ0[]
ε0() = _ε0[]
R() = _R[]
Ry() = _Ry[]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The constants me, mp, q, etc., have been changed from values (in the previous Unitful implementation) to functions. This is a breaking change for any existing code or examples (like examples/vdf.jl) that expect these to be values in arithmetic expressions. If the intention is to maintain the same API, consider using a different approach or ensure that all internal and external usages are updated to call these as functions (e.g., me()).

Comment on lines +7 to +14
const _me = Ref{Any}()
const _mp = Ref{Any}()
const _q = Ref{Any}()
const _k = Ref{Any}()
const _μ0 = Ref{Any}()
const _ε0 = Ref{Any}()
const _R = Ref{Any}()
const _Ry = Ref{Any}()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using Ref{Any} for global constants that are initialized at runtime is a performance anti-pattern in Julia. It forces dynamic dispatch every time these constants are accessed. Since these values are physical constants with units (likely FlexUnits.Quantity), using a more specific type or adding type assertions in the accessor functions would significantly improve performance in hot loops.

Comment on lines +54 to +82
register_unit("Ry" => 13.605693122994 * 1.602176634e-19 * qparse("J"))

# densities
# amucc: amu/cc
register_unit("amucc" => qparse("u/cm^3"))

# velocities
# kms: km/s
register_unit("kms" => qparse("km/s"))

# current densities
# ampm2: μA/m²
register_unit("ampm2" => qparse("μA/m^2"))

# Others
# tm2: nT/m²
register_unit("tm2" => qparse("nT/m^2"))
# vm2: V/m²
register_unit("vm2" => qparse("V/m^2"))

# Physical constants
_me[] = 9.1093837015e-31 * qparse("kg")
_mp[] = 1.67262192369e-27 * qparse("kg")
_q[] = 1.602176634e-19 * qparse("C")
_k[] = 1.380649e-23 * qparse("J/K")
_μ0[] = 4π * 1e-7 * qparse("T*m/A")
_ε0[] = 8.8541878128e-12 * qparse("F/m")
_R[] = 8.31446261815324 * qparse("J/(mol*K)")
_Ry[] = 13.605693122994 * 1.602176634e-19 * qparse("J")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The calculation for the Rydberg constant (Ry) is duplicated. It is calculated once for unit registration and again for the constant storage. It's better to calculate it once and reuse the value.

    ry_val = 13.605693122994 * 1.602176634e-19 * qparse("J")
    # Ry: Rydberg
    register_unit("Ry" => ry_val)

    # ... (other registrations)

    _Ry[] = ry_val

Comment on lines +190 to +191
typeunit = bd.head.headline == "PLANETARY" ? "PLANETARY" :
_get_typeunit(bd.head.headline)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The explicit check for "PLANETARY" here is redundant because _get_typeunit(bd.head.headline) already handles this case and returns "PLANETARY".

        typeunit = _get_typeunit(bd.head.headline)

@codecov

codecov Bot commented May 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.18750% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.97%. Comparing base (ab89902) to head (f99a2a0).

Files with missing lines Patch % Lines
src/unit/FlexUnitsBatsrus.jl 74.13% 30 Missing ⚠️
ext/BatsrusMakieExt/typerecipe.jl 0.00% 5 Missing ⚠️
ext/BatsrusMakieUniformStreamlinesExt/animate.jl 0.00% 3 Missing ⚠️
ext/BatsrusPyPlotExt/animate.jl 0.00% 3 Missing ⚠️
src/plot/plots.jl 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #165      +/-   ##
==========================================
- Coverage   83.05%   82.97%   -0.09%     
==========================================
  Files          21       21              
  Lines        4155     4199      +44     
==========================================
+ Hits         3451     3484      +33     
- Misses        704      715      +11     

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

@github-actions

Copy link
Copy Markdown

Benchmark Results (Julia v1)

Time benchmarks
master f99a2a0... master / f99a2a0...
amrex/load 26 ± 0.55 μs 26.2 ± 0.7 μs 0.989 ± 0.034
amrex/phase_space_3d 6.18 ± 1 ms 6.37 ± 1.2 ms 0.971 ± 0.25
amrex/select_region 0.241 ± 0.011 ms 0.25 ± 0.012 ms 0.964 ± 0.065
amrex/select_region_from_files 0.799 ± 0.061 ms 0.827 ± 0.08 ms 0.966 ± 0.12
read/ASCII 0.742 ± 0.018 ms 0.729 ± 0.011 ms 1.02 ± 0.029
read/Anisotropy 6.91 ± 0.12 μs 6.93 ± 0.17 μs 0.997 ± 0.03
read/Current density 10.3 ± 0.61 μs 11 ± 0.55 μs 0.934 ± 0.073
read/Current density 3D 11.1 ± 0.54 μs 11.1 ± 0.54 μs 0.995 ± 0.069
read/Current density 3D Jx 5.45 ± 0.2 μs 5.35 ± 0.19 μs 1.02 ± 0.052
read/Current density Jz 7.8 ± 0.09 μs 7.81 ± 0.11 μs 0.999 ± 0.018
read/Cutdir 2.4 ± 0.24 μs 2.39 ± 0.31 μs 1 ± 0.16
read/Cutdir subset 3.29 ± 0.3 μs 3.35 ± 0.42 μs 0.982 ± 0.15
read/Extract Bmag 0.581 ± 0.14 μs 0.581 ± 0.14 μs 1 ± 0.34
read/HDF5 0.0835 ± 0.0027 ms 0.0855 ± 0.0027 ms 0.977 ± 0.044
read/HDF5 extract 12.5 ± 0.41 μs 12.5 ± 0.44 μs 1 ± 0.048
read/Interp2d 1.17 ± 0.21 μs 1.05 ± 0.28 μs 1.11 ± 0.36
read/Load binary structured 0.0594 ± 0.0033 ms 0.0478 ± 0.028 ms 1.24 ± 0.73
time_to_load 1.29 ± 0.0037 s 1.49 ± 0.021 s 0.868 ± 0.012
Memory benchmarks
master f99a2a0... master / f99a2a0...
amrex/load 0.212 k allocs: 9.67 kB 0.212 k allocs: 9.67 kB 1
amrex/phase_space_3d 0.059 k allocs: 18.3 MB 0.059 k allocs: 18.3 MB 1
amrex/select_region 3 allocs: 1.07 MB 3 allocs: 1.07 MB 1
amrex/select_region_from_files 0.05 k allocs: 7.48 MB 0.05 k allocs: 7.48 MB 1
read/ASCII 0.395 k allocs: 0.109 MB 0.395 k allocs: 0.109 MB 1
read/Anisotropy 3 allocs: 4.84 kB 3 allocs: 4.84 kB 1
read/Current density 10 allocs: 12.5 kB 10 allocs: 12.5 kB 1
read/Current density 3D 10 allocs: 6.65 kB 10 allocs: 6.65 kB 1
read/Current density 3D Jx 4 allocs: 2.23 kB 4 allocs: 2.23 kB 1
read/Current density Jz 4 allocs: 4.18 kB 4 allocs: 4.18 kB 1
read/Cutdir 0.137 k allocs: 5.98 kB 0.137 k allocs: 5.98 kB 1
read/Cutdir subset 0.159 k allocs: 8.89 kB 0.159 k allocs: 8.89 kB 1
read/Extract Bmag 3 allocs: 4.09 kB 3 allocs: 4.09 kB 1
read/HDF5 0.1 k allocs: 3.67 kB 0.1 k allocs: 3.67 kB 1
read/HDF5 extract 17 allocs: 4.55 kB 17 allocs: 4.55 kB 1
read/Interp2d 12 allocs: 4.45 kB 12 allocs: 4.45 kB 1
read/Load binary structured 0.144 k allocs: 0.0743 MB 0.144 k allocs: 0.0743 MB 1
time_to_load 0.149 k allocs: 11.1 kB 0.149 k allocs: 11.1 kB 1

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.

1 participant