Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/core_init_atmosphere/mpas_init_atm_cases.F
Original file line number Diff line number Diff line change
Expand Up @@ -6882,6 +6882,7 @@ real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surf
integer :: k, lm, lp
real (kind=RKIND) :: wm, wp
real (kind=RKIND) :: slope
real (kind=RKIND) :: lapse_rate

integer :: interp_order, extrap_type
real (kind=RKIND) :: surface, sealevel
Expand Down Expand Up @@ -6933,9 +6934,9 @@ real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surf
slope = (zf(2,nz) - zf(2,nz-1)) / (zf(1,nz) - zf(1,nz-1))
vertical_interp = zf(2,nz) + slope * (target_z - zf(1,nz))
else if (extrap_type == 2) then
call mpas_log_write('extrap_type == 2 not implemented for target_z >= zf(1,nz)', messageType=MPAS_LOG_ERR)
if (present(ierr)) ierr = 1
return
! 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))
Comment on lines +6937 to +6939
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
! 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

Copilot uses AI. Check for mistakes.
end if
return
end if
Expand Down Expand Up @@ -7522,3 +7523,4 @@ end function read_text_array


end module init_atm_cases

24 changes: 23 additions & 1 deletion src/core_init_atmosphere/mpas_init_atm_vinterp.F
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module init_atm_vinterp
!
! Purpose:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surface_val, sealev_val)
real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surface_val, sealev_val, ierr)

implicit none

Expand All @@ -33,10 +33,12 @@ real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surf
integer, intent(in), optional :: extrap
real (kind=RKIND), intent(in), optional :: surface_val
real (kind=RKIND), intent(in), optional :: sealev_val
integer, intent(out), optional :: ierr ! error code: 0 = success, 1 = invalid extrapolation type

integer :: k, lm, lp
real (kind=RKIND) :: wm, wp
real (kind=RKIND) :: slope
real (kind=RKIND) :: lapse_rate

integer :: interp_order, extrap_type
real (kind=RKIND) :: surface, sealevel
Expand Down Expand Up @@ -66,6 +68,11 @@ real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surf
sealevel = 201300.0
end if

! Initialize ierr to 0 (success)
if (present(ierr)) then
ierr = 0
end if

!
! Extrapolation required
!
Expand All @@ -75,6 +82,13 @@ real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surf
else if (extrap_type == 1) then
slope = (zf(2,2) - zf(2,1)) / (zf(1,2) - zf(1,1))
vertical_interp = zf(2,1) + slope * (target_z - zf(1,1))
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))
Comment on lines +85 to +88
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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

Copilot uses AI. Check for mistakes.
else
vertical_interp = zf(2,1)
if (present(ierr)) ierr = 1
end if
return
end if
Expand All @@ -84,6 +98,13 @@ real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surf
else if (extrap_type == 1) then
slope = (zf(2,nz) - zf(2,nz-1)) / (zf(1,nz) - zf(1,nz-1))
vertical_interp = zf(2,nz) + slope * (target_z - zf(1,nz))
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))
Comment on lines +101 to +104
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
else
vertical_interp = zf(2,nz)
if (present(ierr)) ierr = 1
end if
return
end if
Expand All @@ -109,3 +130,4 @@ real (kind=RKIND) function vertical_interp(target_z, nz, zf, order, extrap, surf
end function vertical_interp

end module init_atm_vinterp

Loading