Skip to content

Combine methods to calcualte sati and satw - #79

Merged
jomey merged 22 commits into
mainfrom
topotherm
Sep 18, 2026
Merged

jomey merged 22 commits into
mainfrom
topotherm

Conversation

@jomey

@jomey jomey commented Jul 13, 2026 •

Copy link
Copy Markdown
Member

Introduction of a unified saturation_vapor_pressure function, which replaces direct calls to satw and sati with a single interface in both C and Python code. Additionally, several unused or redundant constants and macros are removed from envphys.h, and the code style is cleaned up for consistency.

The most important changes are:

Saturation Vapor Pressure Refactor:

  • Introduced a new saturation_vapor_pressure(double *temperature) function in C (topotherm.c/envphys_c.h) that selects the appropriate formula (over ice or water) based on temperature, replacing direct calls to satw and sati throughout the codebase.
  • Updated the Python interface and added a Cython wrapper svp_for_temperatures to efficiently apply the new saturation vapor pressure function to arrays.

Code Cleanup:

  • Removed unused or redundant constants and macros from envphys.h
  • Improved code style and header usage in C files for consistency and clarity.
  • Added a "clang-format" to consistently format C code between pysnobal and SMRF

Tests

This will make the AWSM tests fail since we are changing how floating point variables are used and replace a Python with a C calculation. All the changes to the test files are in the range of floating point number differences.
The corresponding PR: iSnobal/awsm/pull/40

Food for thought

This could also be a first template on how to approach the tk less than zero error in pysnobal, by making less of a wild goose chase where and how sati is called. Ideally we would not have the copied code from IPW in SMRF, but then you wouldn't be able to install SMRF without pysnobal. The latter is something I would happily introduce as a library dependency with SMRF since pysnobal is a quick and lightweight install. Thoughts?

jomey added 3 commits July 13, 2026 14:54
This was a 1x1 copy from IPW and is no filtered to what is used within SMRF. Also added
the Stefan-Boltzmann constant.
… code

There was duplicated code for the math to calculate the saturation vapor pressure. One
version for Python and one for the C extension. This combines the math to be only within
C. It also cleans up the `sati` and `satw` function and creates a "neutral" endpoint to
move the decision for ice vs water into a new method. Also adds some references to the
methods itself.
@jomey
jomey requested review from a team and Copilot July 13, 2026 23:36

Copilot AI 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.

Pull request overview

This PR refactors saturation vapor pressure computation in SMRF by introducing a unified saturation_vapor_pressure interface (C + Python), replacing direct usage patterns around satw/sati, and cleaning up related C headers/wrappers. This supports consistent physics behavior across the C kernels and the Python API while reducing duplicated formula logic.

Changes:

  • Added a C-level saturation_vapor_pressure(double *temperature) wrapper and updated C call sites to use it.
  • Updated the Python vapor pressure API to call into a new Cython wrapper (svp_for_temperatures) for array computations.
  • Removed/centralized some constants/macros in envphys.h and added a new unit test for vapor pressure.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
smrf/tests/envphys/test_vapor_pressure.py Adds a unit test for saturation_vapor_pressure.
smrf/envphys/vapor_pressure.py Replaces pure-Python satw/sati with a unified wrapper calling into Cython/C.
smrf/envphys/thermal/topotherm.py Switches thermal calculations to use saturation_vapor_pressure.
smrf/envphys/core/topotherm.c Adds C wrapper saturation_vapor_pressure and refactors satw/sati implementations.
smrf/envphys/core/envphys.h Cleans up constants/macros and introduces LOG_10 and STEF_BOLTZ.
smrf/envphys/core/envphys_c.pyx Adds svp_for_temperatures Cython wrapper and updates extern declarations.
smrf/envphys/core/envphys_c.h Exposes saturation_vapor_pressure in the C API header.
smrf/envphys/core/dewpt.c Updates dew point routines to use the unified saturation vapor pressure wrapper.

Comment thread smrf/envphys/core/topotherm.c Outdated
Comment thread smrf/tests/envphys/test_vapor_pressure.py Outdated
Comment thread smrf/tests/envphys/test_vapor_pressure.py
Comment thread smrf/envphys/vapor_pressure.py Outdated
Comment thread smrf/envphys/core/envphys_c.pyx Outdated
Comment thread smrf/envphys/core/envphys.h Outdated
jomey added 5 commits July 17, 2026 08:49
Turns out that having it as a constants will make tests flaky once the shared mock is
changed or updated as it is the case with the albedo tests.
Missed this call to sati and was indentified by @copilots review.
This uses the same file as pysnobal to create a consistent code style. Also moved one more
constant declaration to envphys.h
jomey added 3 commits July 17, 2026 11:26
Rename satvp to svp_for_celsius since that is all the method does.
Most noteworthy is to use "value != value" as a shortcut to check for NaNs in C.
Update to use numpy memoryviews for future compatibility. Also add/update docstrings.
@jomey jomey added maintenance Technical updates to code base, dependent libraries, package install, or software architecture Cleanup Remove unused, untested, or complex model logic labels Sep 14, 2026
Those are no longer called individually and available via the
saturation_vapor_pressure API
C offers a log10 method that simplifies the math for sati and satw calculations.
Clarify units for temperature
Cleans, builds, and then installs the package in editable mode
Explicitly add these targets before tests and install
Transfer from pysnobal, where a similar commit was done recently.

Copilot explanation:
Defining NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION tells NumPy's headers:
"compile against only the stable post-1.7 API."

This is the same API surface that NumPy 2.x retains — the symbols that were
removed in 2.0 are a strict subset of what was already deprecated before 1.7.

Placing the macro in setup.py's Extension definition means it is applied
uniformly to every .c file compiled in that extension (including the libsnobal
C sources), not just the Cython-generated one.
@arobledano

Copy link
Copy Markdown
Contributor

Ready to pull the trigger...happy to see it finally worked!

Comment thread setup.py
)
"extra_link_args": ["-fopenmp"],
"include_dirs": [numpy.get_include()],
"define_macros": [("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This removes the numpy compile warning

@jomey

jomey commented Sep 17, 2026

Copy link
Copy Markdown
Member Author

Ready to pull the trigger...happy to see it finally worked!

Ready to review including the corresponding AWSM PR. Thank you!

arobledano
arobledano approved these changes Sep 17, 2026 •
@jomey
jomey merged commit 2a2f01e into main Sep 18, 2026
6 checks passed
@jomey
jomey deleted the topotherm branch September 18, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Cleanup Remove unused, untested, or complex model logic maintenance Technical updates to code base, dependent libraries, package install, or software architecture

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants