Implement lapse-rate extrapolation for vertical interpolation (extrap_type == 2)#1413
Implement lapse-rate extrapolation for vertical interpolation (extrap_type == 2)#1413mrixlam wants to merge 1 commit intoMPAS-Dev:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Implements the previously missing extrap_type == 2 (“lapse-rate”) behavior for vertical extrapolation at the upper boundary during init-atmosphere vertical interpolation, preventing fatal errors when the model top exceeds the input data’s vertical range.
Changes:
- Extend
vertical_interpto handleextrap_type == 2fortarget_z >= zf(1,nz)(upper-boundary extrapolation). - Add/standardize an optional
ierroutput on theinit_atm_vinterpimplementation to signal invalid extrapolation types. - Remove the prior “not implemented” fatal-path for
extrap_type == 2inmpas_init_atm_cases.F.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/core_init_atmosphere/mpas_init_atm_vinterp.F |
Adds optional ierr and implements extrap_type==2 for upper/lower boundary extrapolation. |
src/core_init_atmosphere/mpas_init_atm_cases.F |
Replaces the previous fatal error for upper-boundary extrap_type==2 with an extrapolation calculation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| else if (extrap_type == 2) then | ||
| ! Lapse-rate extrapolation: calculate lapse rate from bottom two levels | ||
| lapse_rate = (zf(2,2) - zf(2,1)) / (zf(1,2) - zf(1,1)) | ||
| vertical_interp = zf(2,1) + lapse_rate * (target_z - zf(1,1)) |
There was a problem hiding this comment.
extrap_type == 2 (lapse-rate) is implemented here using the same formula as extrap_type == 1 (linear), i.e., a slope computed from the bottom two levels. That makes the new lapse-rate option behaviorally identical to linear extrapolation. If lapse-rate is intended to be a fixed temperature lapse rate (as in the other vertical_interp implementation in mpas_init_atm_cases.F), please apply that constant lapse rate here (or otherwise document/rename the option so it’s not indistinguishable from linear).
| else if (extrap_type == 2) then | ||
| ! Lapse-rate extrapolation: calculate lapse rate from top two levels | ||
| lapse_rate = (zf(2,nz) - zf(2,nz-1)) / (zf(1,nz) - zf(1,nz-1)) | ||
| vertical_interp = zf(2,nz) + lapse_rate * (target_z - zf(1,nz)) |
There was a problem hiding this comment.
Upper-boundary extrap_type == 2 uses a lapse rate computed from the top two levels, which is mathematically equivalent to the existing extrap_type == 1 linear extrapolation. If lapse-rate is meant to behave differently from linear (e.g., fixed -6.5 K/km), this should be adjusted so the two extrapolation modes are not duplicates.
| ! Lapse-rate extrapolation: calculate lapse rate from top two levels | ||
| lapse_rate = (zf(2,nz) - zf(2,nz-1)) / (zf(1,nz) - zf(1,nz-1)) | ||
| vertical_interp = zf(2,nz) + lapse_rate * (target_z - zf(1,nz)) |
There was a problem hiding this comment.
For extrap_type == 2 (lapse-rate) at the upper boundary, this change computes lapse_rate from the top two levels, which makes it effectively the same as extrap_type == 1 linear extrapolation. In this same function, the lower-boundary lapse-rate branch uses a fixed 0.0065 K/m (line 6926), so the upper and lower implementations are now inconsistent. Please align the two (either both fixed-lapse-rate or both gradient-derived) and ensure linear vs lapse-rate remain meaningfully different options.
| ! Lapse-rate extrapolation: calculate lapse rate from top two levels | |
| lapse_rate = (zf(2,nz) - zf(2,nz-1)) / (zf(1,nz) - zf(1,nz-1)) | |
| vertical_interp = zf(2,nz) + lapse_rate * (target_z - zf(1,nz)) | |
| ! Lapse-rate extrapolation: use fixed lapse rate (0.0065 K/m) | |
| vertical_interp = zf(2,nz) - (target_z - zf(1,nz))*0.0065 |
Summary:
This PR implements the missing lapse-rate extrapolation functionality (extrap_type == 2) for vertical interpolation in the init_atmosphere module. Previously, this extrapolation type was documented but not implemented for the upper boundary condition, causing fatal errors when model top exceeded input data vertical range.
Problem Statement:
When initializing MPAS-Atmosphere with input data (e.g., IFS/ECMWF) that has a top level below or near the model's configured vertical extent (config_ztop), vertical interpolation may require extrapolation beyond available data levels. While the code supported three extrapolation types:
Type 0: Constant (use nearest value)
Type 1: Linear (extend using slope between last two points)
Type 2: Lapse-rate (use atmospheric temperature gradient)
Type 2 (lapse-rate) was not implemented for the upper boundary (target_z >= zf(1,nz)), resulting in this fatal error:
ERROR: extrap_type == 2 not implemented for target_z >= zf(1,nz)
CRITICAL ERROR: Error in interpolation of t(k,iCell) for k=1, iCell=1
This prevented users from using the physically more appropriate lapse-rate extrapolation method via config_extrap_airtemp = 'lapse-rate' in namelist.init_atmosphere.
Files Modified:
src/core_init_atmosphere/mpas_init_atm_vinterp.F (+5 lines, -0 lines)
src/core_init_atmosphere/mpas_init_atm_cases.F (+4 lines, -3 lines)
Testing:
Successfully tested MPAS model initialization with quasi-uniform global 15km quasi-uniform mesh with following specifications:
IFS 137-level input data (model top ~80 km)
Model configuration: 66 vertical levels, 40 km top
config_extrap_airtemp = 'lapse-rate' in namelist