Skip to content

Handle units external to iteration in moist_lapse and lcl#1980

Closed
jthielen wants to merge 2 commits intoUnidata:mainfrom
jthielen:make-iter-units-external
Closed

Handle units external to iteration in moist_lapse and lcl#1980
jthielen wants to merge 2 commits intoUnidata:mainfrom
jthielen:make-iter-units-external

Conversation

@jthielen
Copy link
Collaborator

@jthielen jthielen commented Jul 23, 2021

Description Of Changes

In the process of reviewing #1968, I began experimenting with performance optimizations to moist_lapse to compare against the current implementation and the lookup table approach used there. While my ideal solution of using guvectorize with numba came up short for now (need an ODE solver that works within numba's nopython mode, so something like NumbaLSODA that brings with it dependency troubles, numbakit-ode that's partially held up by some upstream issues, or a home-spun solver with increased maintenance costs), I was able to get around an order of magnitude improvement by moving unit handling outside of the iterator function, as done here.

Since I went ahead and applied analogous changes to lcl, this PR can replace the draft implementation of #1169.

No robust benchmarks were evaluated, but this did speed up pytest tests/calc/test_thermo.py on my workstation from about 3.5 seconds to 0.68 seconds.

The biggest caveat is that this moves the full chain of operations internal to these iterating functions (so any updates to the underlying functions will also have to modify the code here). However, I don't see that as much of a concern, since I'd expect the future plug-gable calculation suite/automated solver "numbafied" internal routines to necessitate refactoring all of that anyways (EDIT: after some later analysis, I doubt that we'll be able to make a robustly plug-able suite while also using numba-complied underlying routines...but that doesn't change the fact that we'll likely be refactoring these internals relatively soon anyways).

Checklist

@jthielen jthielen added Type: Maintenance Updates and clean ups (but not wrong) Area: Calc Pertains to calculations Subarea: Thermo Pertains to thermodynamic calculations and their physical correctness labels Jul 23, 2021
@jthielen jthielen requested review from dcamron and dopplershift July 23, 2021 18:58
@dopplershift
Copy link
Member

Test failures are due to human-imperceptible changes in the plotted moist adiabats.

The repeated code really hurts me, but the benefits are really great. I'm willing to overlook it so long as we open an issue to remind us to do something about it--I'd say just refactor the guts of these calculations into some re-used private helper, but we can wait on that for a bit while we wait for the other things mentioned to shake out.

Just need to fix up some of the naming lint. Also, is there any way we can avoid the disastrous equation formatting by black there?

exporter = Exporter(globals())

sat_pressure_0c = units.Quantity(6.112, 'millibar')
sat_pressure_0c_in_base_units = 611.2
Copy link
Member

Choose a reason for hiding this comment

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

Why not use to_base_units().m with the value right above?

sat_pressure_0c_in_base_units = 611.2
epsilon_in_base_units = mpconsts.epsilon.to_base_units().m
Rd_in_base_units = mpconsts.Rd.to_base_units().m
Lv_in_base_units = mpconsts.Lv.to_base_units().m
Copy link
Member

Choose a reason for hiding this comment

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

Could we go with something like base_unit_lv? mumbles something about stupid bots

Comment on lines +302 to +311
partial_press = (
sat_pressure_0c_in_base_units
* np.exp(17.67 * (t - 273.15) / (t - 29.65))
)
rs = (
epsilon_in_base_units * partial_press
/ (p - partial_press)
)
frac = (
(Rd_in_base_units * t + Lv_in_base_units * rs)
Copy link
Member

Choose a reason for hiding this comment

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

😭

Copy link
Member

Choose a reason for hiding this comment

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

Though this looks less awful without all the comments from the linter interspersed, so maybe it's not as bad.

@jthielen jthielen force-pushed the make-iter-units-external branch from 640029e to 81232b3 Compare July 23, 2021 21:19
@jthielen
Copy link
Collaborator Author

jthielen commented Jul 23, 2021

@dopplershift I updated the base unit constant names, so hopefully that takes care of the bot complaints. It also resulted in shorter names which improved the line wrapping situation. That being said, the formatting was me just instinctively applying black-style wrapping rules, so after the variable rename, I redid the wrapping. Hopefully what is there now is more acceptable?

w.r.t. the test failures, should I regenerate the test image or lower the tolerance?

Also, that sounds good about an eventual refactor to re-used private helpers.

@jthielen
Copy link
Collaborator Author

Also, just because I didn't want to spend too much time working around it, I tweaked the flake8 check to ignore base_unit_ when checking for unit.

@jthielen jthielen force-pushed the make-iter-units-external branch from d65d0c2 to 41d1ccd Compare August 4, 2021 18:34
@jthielen
Copy link
Collaborator Author

Superseded by #2064.

@jthielen jthielen closed this Aug 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Calc Pertains to calculations Subarea: Thermo Pertains to thermodynamic calculations and their physical correctness Type: Maintenance Updates and clean ups (but not wrong)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants