From 231fe82f3ee58a82efd8818dd6c95b47c2a76325 Mon Sep 17 00:00:00 2001 From: Quentin Rodier <quentin.rodier@meteo.fr> Date: Thu, 3 Sep 2020 17:29:55 +0200 Subject: [PATCH] Quentin 03/09/2020: GFS bugfix: vertical interpolation (ver_inter_to_mixed_grid.f90) from the GFS isobaric pressure grid was wrong. Previously, the computation of the altitude of mass points XZMASS_LS (ver_prep_gribex.f90) was done from XZFLUX_LS computed from the orography PZS_LS (in change_gribex_var.f90) as for hybrid vertical coordinate. However, the vertical grid of GFS is isobaric pressure (no orography). Thus, previously the first level of GFS data (at 1000hPa) was interpolated at the first grid level of MNH (orography + ZHAT) leading to strong biais of temperature, wind and so on near high topography. The corrections include : - reading of all levels (31), - add tyeOfFirstFixedSurface argument for SEARCH_FIELD routine to read correctly the orography and geopotential height from the GRIB, - reading the geopotential height in read_all_data_grib_case.f90 for GFS and inject it in the case of vertical interpolation of an isobaric pressure grid in ver_prep_gribex_case. --- src/MNH/modd_prep_real.f90 | 2 + src/MNH/read_all_data_grib_case.f90 | 81 ++++++++++++++++++++++++----- src/MNH/ver_prep_gribex_case.f90 | 5 +- src/SURFEX/mode_read_grib.F90 | 6 ++- 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/src/MNH/modd_prep_real.f90 b/src/MNH/modd_prep_real.f90 index d2d063217..6933ae26a 100644 --- a/src/MNH/modd_prep_real.f90 +++ b/src/MNH/modd_prep_real.f90 @@ -28,6 +28,7 @@ !! Original 05/05 !! 05/06 (I.Mallet) add *_SV_* variables to allow chemical !! initialization from HCHEMFILE +!! 09/20 (Q. Rodier) add geopotential height for GFS GRIB read !------------------------------------------------------------------------------- ! !* 0. DECLARATIONS @@ -70,6 +71,7 @@ REAL :: XLEN2_LS ! Decay scale for small-scale REAL,DIMENSION(:,:), ALLOCATABLE :: XPS_LS ! surface pressure REAL,DIMENSION(:,:), ALLOCATABLE :: XZS_LS ! orography REAL,DIMENSION(:,:), ALLOCATABLE :: XZSMT_LS ! smooth orography +REAL,DIMENSION(:,:,:), ALLOCATABLE :: XGH_LS ! geopotential height REAL,DIMENSION(:,:,:), ALLOCATABLE :: XZFLUX_LS! altitude of pressure points REAL,DIMENSION(:,:,:), ALLOCATABLE :: XZMASS_LS! altitude of mass points REAL,DIMENSION(:,:,:), ALLOCATABLE :: XPMHP_LS ! pressure minus hyd. pressure diff --git a/src/MNH/read_all_data_grib_case.f90 b/src/MNH/read_all_data_grib_case.f90 index 882dc12bb..bc1711560 100644 --- a/src/MNH/read_all_data_grib_case.f90 +++ b/src/MNH/read_all_data_grib_case.f90 @@ -132,6 +132,7 @@ END MODULE MODI_READ_ALL_DATA_GRIB_CASE ! P. Wautelet 14/03/2019: correct ZWS when variable not present in file ! Q. Rodier 27/01/2020: switch of GRIB number ID for Orograpgy and hydrometeors in ARPEGE/AROME in EPyGrAM v1.3.7 ! Q. Rodier 21/04/2020: correction GFS u and v wind component written in the right vertical order +! Q. Rodier 02/09/2020 : Read and interpol geopotential height for interpolation on isobaric surface Grid of NCEP !------------------------------------------------------------------------------- ! !* 0. DECLARATIONS @@ -203,7 +204,7 @@ INTEGER :: ILUOUT0 ! Unit used for output msg. INTEGER :: IRESP ! Return code of FM-routines INTEGER :: IRET ! Return code from subroutines INTEGER(KIND=kindOfInt) :: IRET_GRIB ! Return code from subroutines -INTEGER, PARAMETER :: JP_GFS=26 ! number of pressure levels for GFS model +INTEGER, PARAMETER :: JP_GFS=31 ! number of pressure levels for GFS model REAL :: ZA,ZB,ZC ! Dummy variables REAL :: ZD,ZE,ZF ! | REAL :: ZTEMP ! | @@ -311,6 +312,7 @@ REAL, DIMENSION(:,:), ALLOCATABLE :: ZPF_G ! Pressure (flux point) REAL, DIMENSION(:,:), ALLOCATABLE :: ZPM_G ! Pressure (mass point) REAL, DIMENSION(:,:), ALLOCATABLE :: ZEXNF_G ! Exner fct. (flux point) REAL, DIMENSION(:,:), ALLOCATABLE :: ZEXNM_G ! Exner fct. (mass point) +REAL, DIMENSION(:,:), ALLOCATABLE :: ZGH_G ! Geopotential Height REAL, DIMENSION(:,:), ALLOCATABLE :: ZT_G ! Temperature REAL, DIMENSION(:,:), ALLOCATABLE :: ZQ_G ! Specific humidity REAL, DIMENSION(:), ALLOCATABLE :: ZH_G ! Relative humidity @@ -334,7 +336,7 @@ INTEGER :: IVERSION,ILEVTYPE LOGICAL :: GFIND ! to test if sea wave height is found !--------------------------------------------------------------------------------------- IP_GFS=(/1000,975,950,925,900,850,800,750,700,650,600,550,500,450,400,350,300,& - 250,200,150,100,70,50,30,20,10/)! + 250,200,150,100,70,50,30,20,10,7,5,3,2,1/)! ! TZFILE => NULL() ! @@ -531,15 +533,10 @@ SELECT CASE (IMODEL) END IF ENDIF CASE(10) ! NCEP - DO IVAR=0,222 - CALL SEARCH_FIELD(IGRIB,INUM_ZS,KPARAM=IVAR) + CALL SEARCH_FIELD(IGRIB,INUM_ZS,KDIS=0,KCAT=3,KNUMBER=5,KTFFS=1) IF(INUM_ZS < 0) THEN - WRITE (ILUOUT0,'(A)')'Orography is missing' - ENDIF - END DO - INUM_ZS=218 - WRITE (ILUOUT0,*) 'lsm ',IGRIB(350) - WRITE (ILUOUT0,*) 'orog ',IGRIB(INUM_ZS) + WRITE (ILUOUT0,'(A)')'Orography is missing - abort' + ENDIF END SELECT ZPARAM(:)=-999. CALL GRIB_GET(IGRIB(INUM_ZS),'Nj',INJ,IRET_GRIB) @@ -755,7 +752,7 @@ IF (IMODEL/=10) THEN STOP ENDIF ELSE ! NCEP - ISTARTLEVEL=10 + ISTARTLEVEL=1000 IT=130 IQ=157 CALL SEARCH_FIELD(IGRIB,INUM,KPARAM=IT,KLEV1=ISTARTLEVEL) @@ -813,7 +810,7 @@ ELSE ! NCEP END IF CALL GRIB_GET(IGRIB(INUM),'values',ZQ_G(:,JLOOP1),IRET_GRIB) WRITE (ILUOUT0,*) 'Q ',ILEV1,IRET_GRIB - CALL SEARCH_FIELD(IGRIB,INUM,KPARAM=IT,KLEV1=ILEV1) + CALL SEARCH_FIELD(IGRIB,INUM,KDIS=0,KCAT=0,KNUMBER=0,KLEV1=ILEV1,KTFFS=100) IF (INUM< 0) THEN !callabortstop WRITE(YMSG,*) 'atmospheric temperature level ',JLOOP1,' is missing' @@ -1055,6 +1052,43 @@ ELSE !NCEP END IF DEALLOCATE (ZOUT) + + +!--------------------------------------------------------------------------------------- +!* 2.5.4.2 Read and interpol geopotential height for interpolation on isobaric surface Grid of NCEP +!--------------------------------------------------------------------------------------- +! +ALLOCATE (ZGH_G(ISIZE,INLEVEL)) +! +IF(IMODEL==10) THEN !NCEP with pressure grid only + DO JLOOP1=1, INLEVEL + ILEV1 = IP_GFS(JLOOP1) + WRITE (ILUOUT0,'(A)') ' | Searching geopotential height' + CALL SEARCH_FIELD(IGRIB,INUM,KDIS=0,KCAT=3,KNUMBER=5,KLEV1=ILEV1) + IF (INUM< 0) THEN + !callabortstop + WRITE(YMSG,*) 'Geopoential height level ',JLOOP1,' is missing' + CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_ALL_DATA_GRIB_CASE',YMSG) + END IF + ! + CALL GRIB_GET(IGRIB(INUM),'values',ZGH_G(:,JLOOP1),IRET_GRIB) + CALL GRIB_GET(IGRIB(INUM),'Nj',INJ,IRET_GRIB) + ! + END DO + ! + CALL COORDINATE_CONVERSION(IMODEL,IGRIB(INUM_ZS),IIU,IJU,ZLONOUT,ZLATOUT,& + ZXOUT,ZYOUT,INI,ZPARAM,IINLO) + ! + ALLOCATE(ZOUT(INO)) + ALLOCATE(XGH_LS(IIU,IJU,INLEVEL)) + ! + DO JLOOP1=1, INLEVEL + CALL HORIBL(ZPARAM(3),ZPARAM(4),ZPARAM(5),ZPARAM(6),INT(ZPARAM(2)),IINLO,INI, & + ZGH_G(:,JLOOP1),INO,ZXOUT,ZYOUT,ZOUT,.FALSE.,PTIME_HORI,.FALSE.) + CALL ARRAY_1D_TO_2D (INO,ZOUT,IIU,IJU,XGH_LS(:,:,JLOOP1)) + END DO + DEALLOCATE(ZOUT) +END IF ! !* 2.5.5 Compute atmospheric pressure on MESO-NH grid ! @@ -1911,7 +1945,7 @@ END SUBROUTINE ARRAY_1D_TO_2D !--------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------- !################################################################################# -SUBROUTINE SEARCH_FIELD(KGRIB,KNUM,KPARAM,KDIS,KCAT,KNUMBER,KLEV1) +SUBROUTINE SEARCH_FIELD(KGRIB,KNUM,KPARAM,KDIS,KCAT,KNUMBER,KLEV1,KTFFS) !################################################################################# ! search the grib message corresponding to KPARAM,KLTYPE,KLEV1,KLEV2 in all ! the KGIRB messages @@ -1931,13 +1965,14 @@ INTEGER,INTENT(IN),OPTIONAL :: KDIS ! Discipline (GRIB2) INTEGER,INTENT(IN),OPTIONAL :: KCAT ! Catégorie (GRIB2) INTEGER,INTENT(IN),OPTIONAL :: KNUMBER ! parameterNumber (GRIB2) INTEGER,INTENT(IN),OPTIONAL :: KLEV1 ! Level +INTEGER,INTENT(IN),OPTIONAL :: KTFFS ! TypeOfFirstFixedSurface ! ! Declaration of local variables ! INTEGER :: IFOUND ! Number of correct parameters INTEGER :: ISEARCH ! Number of correct parameters to find INTEGER :: IRET ! error code -INTEGER :: IPARAM,IDIS,ICAT,INUMBER +INTEGER :: IPARAM,IDIS,ICAT,INUMBER,ITFFS INTEGER :: ILEV1 ! Level parameter 1 INTEGER :: JLOOP ! Dummy counter INTEGER :: IVERSION @@ -1955,6 +1990,7 @@ IF (PRESENT(KDIS)) ISEARCH=ISEARCH+1 IF (PRESENT(KCAT)) ISEARCH=ISEARCH+1 IF (PRESENT(KNUMBER)) ISEARCH=ISEARCH+1 IF (PRESENT(KLEV1)) ISEARCH=ISEARCH+1 +IF(PRESENT(KTFFS)) ISEARCH=ISEARCH+1 ! DO JLOOP=1,SIZE(KGRIB) IFOUND = 0 @@ -1967,6 +2003,23 @@ DO JLOOP=1,SIZE(KGRIB) WRITE (ILUOUT0,'(A)')' | ECMWF pseudo-Grib data encountered, skipping field' CYCLE ENDIF + ! + IF (PRESENT(KTFFS)) THEN + CALL GRIB_GET(KGRIB(JLOOP),'typeOfFirstFixedSurface',ITFFS,IRET_GRIB) + IF (IRET_GRIB > 0) THEN + WRITE (ILUOUT0,'(A)')' | Error encountered in the Grib file, skipping field' + CYCLE + ELSE IF (IRET_GRIB == -6) THEN + WRITE (ILUOUT0,'(A)')' | ECMWF pseudo-Grib data encountered, skipping field' + CYCLE + ENDIF + IF (ITFFS==KTFFS) THEN + IFOUND = IFOUND + 1 + ELSE + CYCLE + ENDIF + ENDIF + IF (PRESENT(KPARAM)) THEN IF (IVERSION == 2) THEN CALL GRIB_GET(KGRIB(JLOOP),'paramId',IPARAM,IRET_GRIB) diff --git a/src/MNH/ver_prep_gribex_case.f90 b/src/MNH/ver_prep_gribex_case.f90 index 4368fc4c1..593ba064d 100644 --- a/src/MNH/ver_prep_gribex_case.f90 +++ b/src/MNH/ver_prep_gribex_case.f90 @@ -90,6 +90,8 @@ END MODULE MODI_VER_PREP_GRIBEX_CASE !! May 2006 Remove EPS !! Apr, 09 2018 (J.-P. Chaboureau) add isobaric surface !! Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O +!! Sep, 02, 2020 (Q. Rodier) use of geopotential height instead of +!! height above orography for isobaric surface interpolation !------------------------------------------------------------------------------- ! !* 0. DECLARATIONS @@ -276,8 +278,9 @@ IF (HFILE(1:3)=='ATM') THEN ZU_LS,ZV_LS, & ZW_LS,'FLUX' ) ELSE ! isobaric surfaces (w at mass points) + !Warning, in that case (NCEP only for now) ZZFLUX_LS is not correct (but not used) CALL VER_INTERP_TO_MIXED_GRID('ATM ',.TRUE.,XZS_LS,XZSMT_LS, & - ZZMASS_LS,ZSV_LS, & + XGH_LS,ZSV_LS, & ZZFLUX_LS,XPS_LS,ZPMHP_LS, & ZTHV_LS,ZR_LS, & ZHU_LS, & diff --git a/src/SURFEX/mode_read_grib.F90 b/src/SURFEX/mode_read_grib.F90 index 344ea5967..786f33c2b 100644 --- a/src/SURFEX/mode_read_grib.F90 +++ b/src/SURFEX/mode_read_grib.F90 @@ -514,7 +514,7 @@ SELECT CASE (HINMODEL) CASE ('ECMWF ') CALL READ_GRIB(HGRIB,HINMODEL,KLUOUT,129,IRET,PZS) CASE ('NCEP ') - CALL READ_GRIB(HGRIB,HINMODEL,KLUOUT,228002,IRET,PZS) + CALL READ_GRIB(HGRIB,HINMODEL,KLUOUT,228002,IRET,PZS) CASE ('ARPEGE','MOCAGE') IF (HINMODEL=='ARPEGE' .AND. NGRIB_VERSION==2) THEN CALL READ_GRIB(HGRIB,HINMODEL,KLUOUT,4,IRET,PZS) @@ -536,7 +536,9 @@ IF (IRET /= 0) THEN END IF ! ! Datas given in archives are multiplied by the gravity acceleration -PZS = PZS / XG +IF(HINMODEL /= 'NCEP') THEN + PZS = PZS / XG +END IF ! IF (LHOOK) CALL DR_HOOK('MODE_READ_GRIB:READ_GRIB_ZS',1,ZHOOK_HANDLE) END SUBROUTINE READ_GRIB_ZS -- GitLab