Diff:
--- a/rd_grib2.F
+++ b/rd_grib2.F
@@
- integer :: glevel1, glevel2
+ real :: glevel1, glevel2
@@
-! if ( gfld%ipdtmpl(10) .eq. 106 ) then
- if ( gfld%ipdtmpl(10) .eq. 106 ) then
+! if ( gfld%ipdtmpl(10) .eq. 106 ) then
+ if (( gfld%ipdtmpl(10) .eq. 106 ) .or.
+ & ( gfld%ipdtmpl(10) .eq. 151 )) then !! Added by Prof. Mariusz Figurski, 20250110
if ( ( gfld%ipdtmpl(14) .EQ. -1*(2**07-1) ) .AND.
@@
- glevel1 = 100. * gfld%ipdtmpl(12)*
- & (10.**(-1.*gfld%ipdtmpl(11)))
- glevel2 = 100. * gfld%ipdtmpl(15)*
- & (10.**(-1.*gfld%ipdtmpl(14)))
+ glevel1 = 100. * gfld%ipdtmpl(12)*
+ & (10.**(-1.*gfld%ipdtmpl(11)))
+ glevel2 = 100. * gfld%ipdtmpl(15)*
+ & (10.**(-1.*gfld%ipdtmpl(14)))
+!The following if-block accounts for the 2024 changes to IFS soil fields. They use a local table. 10.01.2024
+!! Added by Prof. Mariusz Figurski, 20250110
+ if (icenter .eq. 98 .and.
+ & gfld%discipline .eq. 2 .and.
+ & (gfld%ipdtmpl(1) .eq. 3 .or.
+ & gfld%ipdtmpl(1) .eq. 0) .and.
+ & gfld%ipdtmpl(10).eq. 151) then
+ glevel1 = gfld%ipdtmpl(12)
+ glevel2 = gfld%ipdtmpl(15)
+ if ( gfld%ipdtmpl(12) .eq. 0) then
+ glevel1 = 0
+ elseif ( gfld%ipdtmpl(12) .eq. 1) then
+ glevel1 = 7
+ elseif ( gfld%ipdtmpl(12) .eq. 2) then
+ glevel1 = 28
+ elseif ( gfld%ipdtmpl(12) .eq. 3) then
+ glevel1 = 100
+ elseif ( gfld%ipdtmpl(12) .eq. 4) then
+ glevel1 = 289
+ endif
+
+ if ( gfld%ipdtmpl(15) .eq. 0) then
+ glevel2 = 0
+ elseif ( gfld%ipdtmpl(15) .eq. 1) then
+ glevel2 = 7
+ elseif ( gfld%ipdtmpl(15) .eq. 2) then
+ glevel2 = 28
+ elseif ( gfld%ipdtmpl(15) .eq. 3) then
+ glevel2 = 100
+ elseif ( gfld%ipdtmpl(15) .eq. 4) then
+ glevel2 = 289
+ endif
+
+ if ( glevel1 .eq. 100. .and.
+ & glevel2 .lt. -1.e+9 ) then
+ glevel2 = 255.
+ endif
+ endif
end if
- TMP8LOOP: do j = 1, maxvar
- if ((g2code(4,j) .eq. 106) .and.
- & (gfld%ipdtmpl(2) .eq. g2code(3,j)) .and.
+ TMP8LOOP: do j = 1, maxvar
+ if (((g2code(4,j) .eq. 106) .or.
+ & (g2code(4,j) .eq. 151)) .and. !! NEW
+ & (gfld%ipdtmpl(1) .eq. g2code(2,j)) .and. !! NEW
+ & (gfld%ipdtmpl(2) .eq. g2code(3,j)) .and.
& (glevel1 .eq. level1(j)) .and.
& ((glevel2 .eq. level2(j)) .or.
& (level2(j) .le. -88))) then
my_field = namvar(j)
exit TMP8LOOP
endif
enddo TMP8LOOP
@@
- elseif(gfld%ipdtmpl(10).eq.106.or.
- & gfld%ipdtmpl(10).eq.1) then
+ elseif(gfld%ipdtmpl(10).eq.106 .or.
+ & gfld%ipdtmpl(10).eq.151 .or. !! NEW
+ & gfld%ipdtmpl(10).eq.1) then
! Misc near ground/surface levels
level=200100.
Suggestions (to make this change safer & future-proof)
Guard equality checks on floating depths
Now that glevel1/glevel2 are real, use tolerance or rounding before comparing to Vtable integers to avoid rare mismatches:
Code:
! replace exact equality with rounded compare
if ( nint(glevel1) == level1(j) .and.
( nint(glevel2) == level2(j) .or. level2(j) <= -88 ) ) then
or
Code:
real, parameter :: EPSC = 0.5
if ( abs(glevel1 - level1(j)) < EPSC .and.
( abs(glevel2 - level2(j)) < EPSC .or. level2(j) <= -88 ) ) then
Isolate the IFS (center=98) soil-layer mapping
Encapsulate the index→depth mapping in a tiny helper for readability and reuse:
Code:
integer function ifs_soil_cm(idx)
integer, intent(in) :: idx
integer, dimension(0:4) :: lut = (/0,7,28,100,289/)
if (idx < 0 .or. idx > 4) then
ifs_soil_cm = -2147483647 ! missing
else
ifs_soil_cm = lut(idx)
end if
end function
Then:
Code:
glevel1 = ifs_soil_cm(gfld%ipdtmpl(12))
glevel2 = ifs_soil_cm(gfld%ipdtmpl(15))
Add a debug breadcrumb when 151-path is used
Behind a higher debug_level, log one line so users can verify the new logic is triggered:
Code:
if ( debug_level > 10 ) call mprintf(.true.,DEBUG,
& "ECMWF soil(151) mapped: [%f,%f] cm", newline=.true., f1=glevel1, f2=glevel2)
Keep the category check consistent in Vtables
You added a match on ipdtmpl(1) (category). Ensure Vtables specify category for these soil entries; otherwise they won’t match. If you need backward-compatibility, guard it:
Code:
logical :: cat_ok
cat_ok = (g2code(2,j) .eq. -99) .or. (gfld%ipdtmpl(1) .eq. g2code(2,j))
Document the new level type
In your developer notes, record that level type 151 is treated like 106 for storage (level=200100. bucket) and that ECMWF local soil-layer indices are mapped to cm depths (0,7,28,100,289).
@figurski what are you thoughts on this above?