diff --git a/ungrib/Variable_Tables/Vtable.ECMWF.IFS.grib2 b/ungrib/Variable_Tables/Vtable.ECMWF.IFS.grib2 new file mode 100644 index 00000000..949b1bd8 --- /dev/null +++ b/ungrib/Variable_Tables/Vtable.ECMWF.IFS.grib2 @@ -0,0 +1,55 @@ +GRIB1| Level| From | To | metgrid | metgrid | metgrid |GRIB2|GRIB2|GRIB2|GRIB2| +Param| Type |Level1|Level2| Name | Units | Description |Discp|Catgy|Param|Level| +-----+------+------+------+----------+----------+------------------------------------------+-----------------------+ + 129 | 100 | * | | GEOPT | m2 s-2 | | 0 | 0 | | 100 | + 156 | 100 | * | | HGT | m | Height | 0 | 3 | 5 | 100 | + 130 | 100 | * | | TT | K | Temperature | 0 | 0 | 0 | 100 | + 131 | 100 | * | | UU | m s-1 | U | 0 | 2 | 2 | 100 | + 132 | 100 | * | | VV | m s-1 | V | 0 | 2 | 3 | 100 | + 157 | 100 | * | | RH | % | Relative Humidity | 0 | 1 | 1 | 100 | + 165 | 1 | 0 | | UU | m s-1 | U At 10 m | 0 | 2 | 2 | 103 | + 166 | 1 | 0 | | VV | m s-1 | V At 10 m | 0 | 2 | 3 | 103 | + 167 | 1 | 0 | | TT | K | Temperature At 2 m | 0 | 0 | 0 | 103 | + 168 | 1 | 0 | | DEWPT | K | | 0 | 0 | 6 | 103 | + | 1 | 0 | | RH | % | Relative Humidity At 2 m | 0 | 0 | | 103 | + 172 | 1 | 0 | | LANDSEA | 0/1 Flag | Land/Sea flag | 2 | 0 | 0 | 1 | + 129 | 1 | 0 | | SOILGEO | m2 s-2 | | 0 | 0 | | 103 | + 156 | 1 | 0 | | SOILHGT | m | Terrain field of source analysis | 0 | 0 | | 106 | + 134 | 1 | 0 | | PSFC | Pa | Surface Pressure | 0 | 3 | 0 | 1 | + 151 | 1 | 0 | | PMSL | Pa | Sea-level Pressure | 0 | 3 | 0 | 101 | + 235 | 1 | 0 | | SKINTEMP | K | Sea-Surface Temperature | 0 | 3 | | 101 | + 31 | 1 | 0 | | SEAICE | 0/1 Flag | Sea-Ice-Flag | 0 | 3 | | 101 | + 34 | 1 | 0 | | SST | K | Sea-Surface Temperature | 0 | 3 | | 101 | + 141 | 1 | 0 | | SNOW_EC | m | | 0 | 3 | | 101 | + | 1 | 0 | | SNOW | kg m-2 |Water Equivalent of Accumulated Snow Depth| 0 | 3 | | 101 | + 139 | 112 | 0 | 7 | ST000007 | K | T of 0-7 cm ground layer | 2 | 0 | 2 | 106 | + 170 | 112 | 7 | 28 | ST007028 | K | T of 7-28 cm ground layer | 192 | 128 | 170 | 106 | + 183 | 112 | 28 | 100 | ST028100 | K | T of 28-100 cm ground layer | 192 | 128 | 183 | 106 | + 236 | 112 | 100 | 255 | ST100289 | K | T of 100-289 cm ground layer | 192 | 128 | 236 | 106 | + 39 | 112 | 0 | 7 | SM000007 | fraction | Soil moisture of 0-7 cm ground layer | 192 | 128 | 39 | 106 | + 40 | 112 | 7 | 28 | SM007028 | fraction | Soil moisture of 7-28 cm ground layer | 192 | 128 | 40 | 106 | + 41 | 112 | 28 | 100 | SM028100 | fraction | Soil moisture of 28-100 cm ground layer | 192 | 128 | 41 | 106 | + 42 | 112 | 100 | 255 | SM100289 | fraction | Soil moisture of 100-289 cm ground layer | 192 | 128 | 42 | 106 | + 0 | 1 | 0 | 7 | ST000007 | K | T of 0-7 cm ground layer | 2 | 3 | 18 | 151 | + 1 | 2 | 7 | 28 | ST007028 | K | T of 7-28 cm ground layer | 2 | 3 | 18 | 151 | + 2 | 3 | 28 | 100 | ST028100 | K | T of 28-100 cm ground layer | 2 | 3 | 18 | 151 | + 3 | 4 | 100 | 289 | ST100289 | K | T of 100-289 cm ground layer | 2 | 3 | 18 | 151 | + 0 | 1 | 0 | 7 | SM000007 | fraction | Soil moisture of 0-7 cm ground layer | 2 | 0 | 25 | 151 | + 1 | 2 | 7 | 28 | SM007028 | fraction | Soil moisture of 7-28 cm ground layer | 2 | 0 | 25 | 151 | + 2 | 3 | 28 | 100 | SM028100 | fraction | Soil moisture of 28-100 cm ground layer | 2 | 0 | 25 | 151 | + 3 | 4 | 100 | 289 | SM100289 | fraction | Soil moisture of 100-289 cm ground layer | 2 | 0 | 25 | 151 | +-----+------+------+------+----------+----------+------------------------------------------+-----+-----+-----+-----+ +# +# Vtable for the ECMWF IFS output that can be found at: +# https://data.ecmwf.int/forecasts/ccyymmdd/12z/ifs/0p25/oper/ +# +# output includes 13 p-levels (mandatory levels only). 0 to 360-h every 6-h +# +# This Vtable will work with IFS output from before November 2024 (soil level code 106) +# and after Nov 2024 (soil level code 151). If more IFS soil levels are added in the future +# they can be decoded by modifying the Vtable soil fields. Column 1 is the start +# level number, column 2 is the end level number. Columns 3 and 4 contain the +# depth of those levels in cm. +# +# This Vtable has not been tested on any other EC output. + diff --git a/ungrib/src/ngl/g2/params.f b/ungrib/src/ngl/g2/params.f index 3bd09035..7ded1d39 100644 --- a/ungrib/src/ngl/g2/params.f +++ b/ungrib/src/ngl/g2/params.f @@ -40,7 +40,7 @@ module params ! !$$$ - integer,parameter :: MAXPARAM=832 + integer,parameter :: MAXPARAM=842 type gribparam integer :: g1tblver @@ -902,6 +902,17 @@ module params data paramlist(830) /gribparam(2,255,0,1,19,'PTYPE')/ data paramlist(831) /gribparam(2,255,0,6,11,'CDCB')/ data paramlist(832) /gribparam(2,255,0,6,12,'CDCTOP')/ +! Added 04/14/25 for ECMWF IFS + data paramlist(833) /gribparam(2,255,2,3,18,'SOT ')/ + data paramlist(834) /gribparam(2,255,2,0,25,'VSW ')/ + data paramlist(835) /gribparam(2,255,192,128,39,'SWVL1')/ + data paramlist(836) /gribparam(2,255,192,128,40,'SWVL2')/ + data paramlist(837) /gribparam(2,255,192,128,41,'SWVL3')/ + data paramlist(838) /gribparam(2,255,192,128,42,'SWVL4')/ + data paramlist(839) /gribparam(2,255,192,128,139,'STL1 ')/ + data paramlist(840) /gribparam(2,255,192,128,170,'STL2 ')/ + data paramlist(841) /gribparam(2,255,192,128,183,'STL3 ')/ + data paramlist(842) /gribparam(2,255,192,128,236,'STL4 ')/ contains diff --git a/ungrib/src/rd_grib2.F b/ungrib/src/rd_grib2.F index 5a584384..32f176b3 100644 --- a/ungrib/src/rd_grib2.F +++ b/ungrib/src/rd_grib2.F @@ -115,6 +115,7 @@ SUBROUTINE rd_grib2(junit, gribflnm, hdate, ! Open a byte-addressable file. CALL BAOPENR(junit,gribflnm,IOS) first = .true. + if (ios.eq.0) then VERSION: do @@ -240,7 +241,6 @@ SUBROUTINE rd_grib2(junit, gribflnm, hdate, ! Indicator of model (or whatever) which generated the data. iprocess = gfld%ipdtmpl(5) - if (icenter.eq.7) then if (iprocess.eq.81) then map%source = 'NCEP GFS Analysis' @@ -732,7 +732,20 @@ SUBROUTINE rd_grib2(junit, gribflnm, hdate, & (10.**(-1.*gfld%ipdtmpl(11))) glevel2 = 100. * gfld%ipdtmpl(15)* & (10.**(-1.*gfld%ipdtmpl(14))) - end if +! The following if-block accounts for 2024 changes to IFS soil fields. +! They use a local table and a level greater than 255 which ungrib cannot unpack. + if (icenter .eq. 98 .and. + & gfld%discipline .eq. 192 .and. + & gfld%ipdtmpl(1) .eq. 128 .and. + & gfld%ipdtmpl(10).eq. 106) then + glevel1 = gfld%ipdtmpl(12) + glevel2 = gfld%ipdtmpl(15) + if ( glevel1 .eq. 100. .and. + & glevel2 .lt. -1.e+9 ) then + glevel2 = 255. + endif + endif ! IFS test + end if ! ipdtmpl 14/15 test TMP8LOOP: do j = 1, maxvar if ((g2code(4,j) .eq. 106) .and. & (gfld%ipdtmpl(2) .eq. g2code(3,j)) .and. @@ -750,9 +763,31 @@ SUBROUTINE rd_grib2(junit, gribflnm, hdate, cycle MATCH_LOOP endif !MGD if (debug_level .gt. 50) write(6,*) 'my_field is now ',my_field - endif + endif ! end of 106 processing + + if ( gfld%ipdtmpl(10) .eq. 151 ) then + ! post Nov 2024 IFS soil level processing + ! level values are in the grib1 columns in the Vtable + TMP9LOOP: do j = 1, maxvar + if ((g2code(4,j) .eq. 151) .and. + & (gfld%ipdtmpl(2) .eq. g2code(3,j)) .and. + & (gfld%ipdtmpl(12) .eq. gcode(j)) .and. + & (gfld%ipdtmpl(15) .eq. lcode(j)) ) then + glevel1 = level1(j) + glevel2 = level2(j) + my_field = namvar(j) + exit TMP9LOOP + endif + enddo TMP9LOOP + if (j .gt. maxvar ) then + write(6,'(a,i3,a,i3,a)') 'Soil levels ', + & gfld%ipdtmpl(12),' and ',gfld%ipdtmpl(15), + & ' in the GRIB2 file, were not found in the Vtable' + cycle MATCH_LOOP + endif + endif ! end of 151 processing - ! Level (eg. 10000 mb) + ! Assign the proper level (eg. Pressure level, sigma level, or surface) if(gfld%ipdtmpl(10).eq.100) then ! Pressure level (range from 1000mb to 0mb) level=gfld%ipdtmpl(12) * @@ -786,8 +821,9 @@ SUBROUTINE rd_grib2(junit, gribflnm, hdate, & (gfld%ipdtmpl(10).eq.10) ) then ! NCEP cloud layers used for plotting level=200100. - elseif(gfld%ipdtmpl(10).eq.106.or. - & gfld%ipdtmpl(10).eq.1) then + elseif(gfld%ipdtmpl(10).eq.106.or. ! soil levels + & gfld%ipdtmpl(10).eq.1 .or. + & gfld%ipdtmpl(10).eq.151) then ! ecmwf soil ! Misc near ground/surface levels level=200100. elseif(gfld%ipdtmpl(10).eq.6) then diff --git a/util/uncompress_ifs.csh b/util/uncompress_ifs.csh new file mode 100755 index 00000000..cd40b6db --- /dev/null +++ b/util/uncompress_ifs.csh @@ -0,0 +1,39 @@ +#!/bin/csh +# +# A simple uncompress script for NCAR's derecho to convert +# files that use ccsds compression to a standard grib2 which +# can be processed by ungrib. Uses grib_set from eccodes. +# +# +set echo + +module load ncarenv/23.09 intel/2024.2.1 +module load eccodes/2.36.0 + +set workdir = ./ +cd $workdir + +# Create a file list of the downloaded ifs files + +set files = `ls -l 20*oper-fc.grib2 | awk '{print $9}' ` + +foreach f ( $files ) +# file names are of the following form 20241012000000-0h-oper-fc.grib2 + set fname = `echo $f | cut -c1-10` + set h = `echo $f | cut -c19-19` + if ( `echo $f | cut -c19-19` == 'h' ) then + set fhr = `echo $f | cut -c16-18` + else if ( `echo $f | cut -c18-18` == 'h' ) then + set fhr = '0'`echo $f | cut -c16-17` + else + set fhr = '00'`echo $f | cut -c16-16` + endif + set newname = 'ifs.'${fname}.f${fhr}.grib2 + + cp ${f} ${fname}_ccsds.grb2 # work on a copy + + grib_set -r -w packingType=grid_ccsds -s packingType=grid_simple ${fname}_ccsds.grb2 ${newname} + + if ( $status == 0 ) /bin/rm ${fname}_ccsds.grb2 # if successful delete the compressed file copy + +end