From b5759b333e200f51c0fec345a89e6144829b0505 Mon Sep 17 00:00:00 2001 From: Rolf Reichle Date: Sat, 21 Dec 2024 11:55:37 -0500 Subject: [PATCH 1/5] first edits towards reading M21C surface met forcing (NOT YET COMPLETE) (LDAS_Forcing.F90) --- GEOSmetforce_GridComp/LDAS_Forcing.F90 | 69 +++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/GEOSmetforce_GridComp/LDAS_Forcing.F90 b/GEOSmetforce_GridComp/LDAS_Forcing.F90 index b87e673..f7fe8f4 100755 --- a/GEOSmetforce_GridComp/LDAS_Forcing.F90 +++ b/GEOSmetforce_GridComp/LDAS_Forcing.F90 @@ -3091,6 +3091,8 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & ! - updated comments ! ! qliu+reichle, 5 Dec 2023 - added GEOS-IT + ! + ! rreichle, 18 Dec 2024 - added M21C ! ! ----------------------------------- ! @@ -3163,6 +3165,7 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & integer, parameter :: N_MERRA_vars = 13 integer, parameter :: N_MERRA2_vars = 12 ! same as for G5DAS (excl Aerosol vars) integer, parameter :: N_Aerosol_vars = 60 ! additional aerosol forcing vars for GOSWIM (w/ MERRA-2 only for now) + integer, parameter :: N_M21C_vars = 12 integer, parameter :: N_MERRA2plusAerosol_vars = N_MERRA2_vars + N_Aerosol_vars @@ -3175,6 +3178,8 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & character(40), dimension(N_MERRA_vars, N_defs_cols) :: MERRA_defs character(40), dimension(N_MERRA2plusAerosol_vars, N_defs_cols) :: M2INT_defs character(40), dimension(N_MERRA2plusAerosol_vars, N_defs_cols) :: M2COR_defs + character(40), dimension(N_M21C_vars, N_defs_cols) :: M21CINT_defs + character(40), dimension(N_M21C_vars, N_defs_cols) :: M21CCOR_defs character(40), dimension(:,:), allocatable :: GEOSgcm_defs @@ -3272,6 +3277,64 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & GEOSIT_defs(12,3) = 'lfo_inst_1hr_glo_L576x361_slv ' + ! ----------------------------------------------------------------------- + ! + ! define M21C file specs + ! + ! M21C file specs with uncorrected (AGCM) precip from the "int" Collection + ! (ie, the precip generated by the AGCM within the M21C system) + ! + ! NOTE: This is *NOT* the precipitation seen by the land surface in the M21C system. + ! +? ! NOTE: Use SWGDN from the "rad" Collection because SWGDN in MERRA-2 "lfo" +? ! is averaged over land tiles only, unlike all other variables, +? ! which are global, as is SWGDN in the FP "lfo" files. +? ! - reichle, 7 Dec 2015 + + M21CINT_defs( 1,:)=[character(len=40):: 'SWGDN ','tavg','tavg1_2d_rad_Nx','diag','F'] ! use "rad" Collection + M21CINT_defs( 2,:)=[character(len=40):: 'LWGAB ','tavg','tavg1_2d_lfo_Nx','diag','F'] + M21CINT_defs( 3,:)=[character(len=40):: 'PARDR ','tavg','tavg1_2d_lfo_Nx','diag','F'] + M21CINT_defs( 4,:)=[character(len=40):: 'PARDF ','tavg','tavg1_2d_lfo_Nx','diag','F'] + M21CINT_defs( 5,:)=[character(len=40):: 'PRECCU ','tavg','tavg1_2d_int_Nx','diag','F'] ! uncorrected + M21CINT_defs( 6,:)=[character(len=40):: 'PRECLS ','tavg','tavg1_2d_int_Nx','diag','F'] ! uncorrected + M21CINT_defs( 7,:)=[character(len=40):: 'PRECSN ','tavg','tavg1_2d_int_Nx','diag','F'] ! uncorrected + M21CINT_defs( 8,:)=[character(len=40):: 'PS ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CINT_defs( 9,:)=[character(len=40):: 'HLML ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CINT_defs(10,:)=[character(len=40):: 'TLML ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CINT_defs(11,:)=[character(len=40):: 'QLML ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CINT_defs(12,:)=[character(len=40):: 'SPEEDLML','inst','inst1_2d_lfo_Nx','diag','S'] + + + ! MERRA-2 file specs with corrected precip, which could be either + ! - native (ie, the precip seen by the land surface in the MERRA-2 system), or + ! - corrected in post-processing using MERRA-2 (uncorrected) precip as the background + ! The default is to use MERRA-2 native precip corrections. If the "met_tag" includes + ! an optional "__prec[xyz]" string, the precip corrections specified by [xyz] are used. + ! + ! NOTE: This is *NOT* the same as the corrected precipitation of the off-line + ! spin-up run used to generate the MERRA-2 land surface initial conditions + ! for each stream. These precip files used for that have a MERRA background. + ! + ! NOTE: Use SWGDN from the "rad" Collection (see comment above). + + M21CCOR_defs( 1,:)=[character(len=40):: 'SWGDN ','tavg','tavg1_2d_rad_Nx','diag','F'] ! use "rad" Collection + M21CCOR_defs( 2,:)=[character(len=40):: 'LWGAB ','tavg','tavg1_2d_lfo_Nx','diag','F'] + M21CCOR_defs( 3,:)=[character(len=40):: 'PARDR ','tavg','tavg1_2d_lfo_Nx','diag','F'] + M21CCOR_defs( 4,:)=[character(len=40):: 'PARDF ','tavg','tavg1_2d_lfo_Nx','diag','F'] + M21CCOR_defs( 5,:)=[character(len=40):: 'PRECCUCORR ','tavg','tavg1_2d_lfo_Nx','diag','F'] ! MERRA-2 built-in corrections + M21CCOR_defs( 6,:)=[character(len=40):: 'PRECLSCORR ','tavg','tavg1_2d_lfo_Nx','diag','F'] ! MERRA-2 built-in corrections + M21CCOR_defs( 7,:)=[character(len=40):: 'PRECSNOCORR','tavg','tavg1_2d_lfo_Nx','diag','F'] ! MERRA-2 built-in corrections + M21CCOR_defs( 8,:)=[character(len=40):: 'PS ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CCOR_defs( 9,:)=[character(len=40):: 'HLML ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CCOR_defs(10,:)=[character(len=40):: 'TLML ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CCOR_defs(11,:)=[character(len=40):: 'QLML ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CCOR_defs(12,:)=[character(len=40):: 'SPEEDLML ','inst','inst1_2d_lfo_Nx','diag','S'] + + + ! ----------------------------------------------------------------------- + ! + ! define MERRA-2 file specs + ! ! MERRA-2 file specs with uncorrected (AGCM) precip from the "int" Collection ! (ie, the precip generated by the AGCM within the MERRA-2 system) ! @@ -3443,8 +3506,10 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & M2COR_defs(71,:)=[character(len=40):: 'SSSD004 ','tavg','tavg1_2d_adg_Nx','diag','F'] M2COR_defs(72,:)=[character(len=40):: 'SSSD005 ','tavg','tavg1_2d_adg_Nx','diag','F'] - - ! MERRA file specs + + ! ----------------------------------------------------------------------- + ! + ! define (original) MERRA file specs ! ! use *only* "tavg" files b/c "bkg.sfc" files are available only every 6h ! From dc679fe7a793e8492b8d1f796a704db9cfdb4b40 Mon Sep 17 00:00:00 2001 From: Rolf Reichle Date: Wed, 22 Jan 2025 17:58:15 -0500 Subject: [PATCH 2/5] additional edits towards using M21C surface met forcing (LDAS_Forcing.F90) --- CHANGELOG.md | 3 +- GEOSmetforce_GridComp/LDAS_Forcing.F90 | 309 +++++++++++++++++++++---- 2 files changed, 269 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ab148b..8f4ad3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- New update_type for joint 3d soil moisture and 1d snow analysis (Tb+sfmc+sfds+SCF obs) +- New update_type for joint 3d soil moisture and 1d snow analysis (Tb+sfmc+sfds+SCF obs). +- Use M21C surface met forcing. ### Changed diff --git a/GEOSmetforce_GridComp/LDAS_Forcing.F90 b/GEOSmetforce_GridComp/LDAS_Forcing.F90 index f7fe8f4..5c7bca7 100755 --- a/GEOSmetforce_GridComp/LDAS_Forcing.F90 +++ b/GEOSmetforce_GridComp/LDAS_Forcing.F90 @@ -3180,6 +3180,8 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & character(40), dimension(N_MERRA2plusAerosol_vars, N_defs_cols) :: M2COR_defs character(40), dimension(N_M21C_vars, N_defs_cols) :: M21CINT_defs character(40), dimension(N_M21C_vars, N_defs_cols) :: M21CCOR_defs + character(40), dimension(N_M21C_vars, N_defs_cols) :: M21CCSINT_defs + character(40), dimension(N_M21C_vars, N_defs_cols) :: M21CCSCOR_defs character(40), dimension(:,:), allocatable :: GEOSgcm_defs @@ -3285,50 +3287,69 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & ! (ie, the precip generated by the AGCM within the M21C system) ! ! NOTE: This is *NOT* the precipitation seen by the land surface in the M21C system. - ! -? ! NOTE: Use SWGDN from the "rad" Collection because SWGDN in MERRA-2 "lfo" -? ! is averaged over land tiles only, unlike all other variables, -? ! which are global, as is SWGDN in the FP "lfo" files. -? ! - reichle, 7 Dec 2015 - - M21CINT_defs( 1,:)=[character(len=40):: 'SWGDN ','tavg','tavg1_2d_rad_Nx','diag','F'] ! use "rad" Collection - M21CINT_defs( 2,:)=[character(len=40):: 'LWGAB ','tavg','tavg1_2d_lfo_Nx','diag','F'] - M21CINT_defs( 3,:)=[character(len=40):: 'PARDR ','tavg','tavg1_2d_lfo_Nx','diag','F'] - M21CINT_defs( 4,:)=[character(len=40):: 'PARDF ','tavg','tavg1_2d_lfo_Nx','diag','F'] - M21CINT_defs( 5,:)=[character(len=40):: 'PRECCU ','tavg','tavg1_2d_int_Nx','diag','F'] ! uncorrected - M21CINT_defs( 6,:)=[character(len=40):: 'PRECLS ','tavg','tavg1_2d_int_Nx','diag','F'] ! uncorrected - M21CINT_defs( 7,:)=[character(len=40):: 'PRECSN ','tavg','tavg1_2d_int_Nx','diag','F'] ! uncorrected - M21CINT_defs( 8,:)=[character(len=40):: 'PS ','inst','inst1_2d_lfo_Nx','diag','S'] - M21CINT_defs( 9,:)=[character(len=40):: 'HLML ','inst','inst1_2d_lfo_Nx','diag','S'] - M21CINT_defs(10,:)=[character(len=40):: 'TLML ','inst','inst1_2d_lfo_Nx','diag','S'] - M21CINT_defs(11,:)=[character(len=40):: 'QLML ','inst','inst1_2d_lfo_Nx','diag','S'] - M21CINT_defs(12,:)=[character(len=40):: 'SPEEDLML','inst','inst1_2d_lfo_Nx','diag','S'] - - ! MERRA-2 file specs with corrected precip, which could be either - ! - native (ie, the precip seen by the land surface in the MERRA-2 system), or - ! - corrected in post-processing using MERRA-2 (uncorrected) precip as the background - ! The default is to use MERRA-2 native precip corrections. If the "met_tag" includes + M21CINT_defs( 1,:)=[character(len=40):: 'SWGDN ', 'tavg','lfo_tavg_1hr_glo_L1152x721_slv', 'diag','F'] + M21CINT_defs( 2,:)=[character(len=40):: 'LWGAB ', 'tavg','lfo_tavg_1hr_glo_L1152x721_slv', 'diag','F'] + M21CINT_defs( 3,:)=[character(len=40):: 'PARDR ', 'tavg','lfo_tavg_1hr_glo_L1152x721_slv', 'diag','F'] + M21CINT_defs( 4,:)=[character(len=40):: 'PARDF ', 'tavg','lfo_tavg_1hr_glo_L1152x721_slv', 'diag','F'] + M21CINT_defs( 5,:)=[character(len=40):: 'PRECRAINCU', 'tavg','int_tavg_1hr_glo_L1152x721_slv', 'diag','F'] ! uncorrected + M21CINT_defs( 6,:)=[character(len=40):: 'PRECRAINLS', 'tavg','int_tavg_1hr_glo_L1152x721_slv', 'diag','F'] ! uncorrected + M21CINT_defs( 7,:)=[character(len=40):: 'PRECSNO ', 'tavg','int_tavg_1hr_glo_L1152x721_slv', 'diag','F'] ! uncorrected + M21CINT_defs( 8,:)=[character(len=40):: 'PS ', 'inst','lfo_inst_1hr_glo_L1152x721_slv', 'diag','S'] + M21CINT_defs( 9,:)=[character(len=40):: 'HLML ', 'inst','lfo_inst_1hr_glo_L1152x721_slv', 'diag','S'] + M21CINT_defs( 10,:)=[character(len=40):: 'TLML ', 'inst','lfo_inst_1hr_glo_L1152x721_slv', 'diag','S'] + M21CINT_defs( 11,:)=[character(len=40):: 'QLML ', 'inst','lfo_inst_1hr_glo_L1152x721_slv', 'diag','S'] + M21CINT_defs( 12,:)=[character(len=40):: 'SPEEDLML ', 'inst','lfo_inst_1hr_glo_L1152x721_slv', 'diag','S'] + + ! same but for cube-sphere lfo (only works when using matching c360 tile space for simulation) + + M21CCSINT_defs = M21CINT_defs + + M21CCSINT_defs( 1,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] + M21CCSINT_defs( 2,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] + M21CCSINT_defs( 3,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] + M21CCSINT_defs( 4,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] + M21CCSINT_defs( 5,3)=[character(len=40):: 'int_tavg_1hr_glo_C360x360x6_slv' ] ! uncorrected + M21CCSINT_defs( 6,3)=[character(len=40):: 'int_tavg_1hr_glo_C360x360x6_slv' ] ! uncorrected + M21CCSINT_defs( 7,3)=[character(len=40):: 'int_tavg_1hr_glo_C360x360x6_slv' ] ! uncorrected + M21CCSINT_defs( 8,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + M21CCSINT_defs( 9,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + M21CCSINT_defs(10,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + M21CCSINT_defs(11,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + M21CCSINT_defs(12,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + + ! M21C file specs with corrected precip, which could be either + ! - native (ie, the precip seen by the land surface in the M21C system), or + ! - corrected in post-processing using M21C (uncorrected) precip as the background + ! The default is to use M21C native precip corrections. If the "met_tag" includes ! an optional "__prec[xyz]" string, the precip corrections specified by [xyz] are used. ! - ! NOTE: This is *NOT* the same as the corrected precipitation of the off-line - ! spin-up run used to generate the MERRA-2 land surface initial conditions - ! for each stream. These precip files used for that have a MERRA background. - ! - ! NOTE: Use SWGDN from the "rad" Collection (see comment above). + ! NOTE: This is *NOT* the same as the corrected precipitation of the off-line + ! spin-up run used to generate the M21C land surface initial conditions + ! for each stream. These precip files used for that have a MERRA-2 background. + + M21CCOR_defs = M21CINT_defs + + M21CCOR_defs( 5,:)=[character(len=40):: 'PRECRAINCUCORR','tavg','lfo_tavg_1hr_glo_L1152x721_slv', 'diag','F'] ! M21C built-in corrections + M21CCOR_defs( 6,:)=[character(len=40):: 'PRECRAINLSCORR','tavg','lfo_tavg_1hr_glo_L1152x721_slv', 'diag','F'] ! M21C built-in corrections + M21CCOR_defs( 7,:)=[character(len=40):: 'PRECSNOCORR ','tavg','lfo_tavg_1hr_glo_L1152x721_slv', 'diag','F'] ! M21C built-in corrections + + ! same but for cube-sphere lfo (only works when using matching c360 tile space for simulation) - M21CCOR_defs( 1,:)=[character(len=40):: 'SWGDN ','tavg','tavg1_2d_rad_Nx','diag','F'] ! use "rad" Collection - M21CCOR_defs( 2,:)=[character(len=40):: 'LWGAB ','tavg','tavg1_2d_lfo_Nx','diag','F'] - M21CCOR_defs( 3,:)=[character(len=40):: 'PARDR ','tavg','tavg1_2d_lfo_Nx','diag','F'] - M21CCOR_defs( 4,:)=[character(len=40):: 'PARDF ','tavg','tavg1_2d_lfo_Nx','diag','F'] - M21CCOR_defs( 5,:)=[character(len=40):: 'PRECCUCORR ','tavg','tavg1_2d_lfo_Nx','diag','F'] ! MERRA-2 built-in corrections - M21CCOR_defs( 6,:)=[character(len=40):: 'PRECLSCORR ','tavg','tavg1_2d_lfo_Nx','diag','F'] ! MERRA-2 built-in corrections - M21CCOR_defs( 7,:)=[character(len=40):: 'PRECSNOCORR','tavg','tavg1_2d_lfo_Nx','diag','F'] ! MERRA-2 built-in corrections - M21CCOR_defs( 8,:)=[character(len=40):: 'PS ','inst','inst1_2d_lfo_Nx','diag','S'] - M21CCOR_defs( 9,:)=[character(len=40):: 'HLML ','inst','inst1_2d_lfo_Nx','diag','S'] - M21CCOR_defs(10,:)=[character(len=40):: 'TLML ','inst','inst1_2d_lfo_Nx','diag','S'] - M21CCOR_defs(11,:)=[character(len=40):: 'QLML ','inst','inst1_2d_lfo_Nx','diag','S'] - M21CCOR_defs(12,:)=[character(len=40):: 'SPEEDLML ','inst','inst1_2d_lfo_Nx','diag','S'] + M21CCSCOR_defs = M21CCOR_defs + + M21CCSCOR_defs( 1,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] + M21CCSCOR_defs( 2,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] + M21CCSCOR_defs( 3,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] + M21CCSCOR_defs( 4,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] + M21CCSCOR_defs( 5,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] ! M21C built-in corrections + M21CCSCOR_defs( 6,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] ! M21C built-in corrections + M21CCSCOR_defs( 7,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] ! M21C built-in corrections + M21CCSCOR_defs( 8,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + M21CCSCOR_defs( 9,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + M21CCSCOR_defs(10,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + M21CCSCOR_defs(11,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + M21CCSCOR_defs(12,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] ! ----------------------------------------------------------------------- @@ -3614,6 +3635,47 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & call parse_MERRA_met_tag( met_path, met_tag, date_time_bkwd, & met_path_bkwd, prec_path_bkwd, met_tag_bkwd, use_prec_corr ) + + elseif (met_tag(1:4)=='M21C') then ! M21C (must check M21C before MERRA-2 because MERRA2 uses "M2") + + N_GEOSgcm_vars = N_M21C_vars + + allocate(GEOSgcm_defs(N_GEOSgcm_vars,N_defs_cols)) + + if (met_tag(1:7)=='M21CINT') then + + GEOSgcm_defs(1:N_GEOSgcm_vars,:) = M21CINT_defs( 1:N_GEOSgcm_vars,:) + + elseif (met_tag(1:7)=='M21CCOR') then + + GEOSgcm_defs(1:N_GEOSgcm_vars,:) = M21CCOR_defs( 1:N_GEOSgcm_vars,:) + + elseif (met_tag(1:9)=='M21CCSINT') then + + GEOSgcm_defs(1:N_GEOSgcm_vars,:) = M21CCSINT_defs(1:N_GEOSgcm_vars,:) + + elseif (met_tag(1:9)=='M21CCSCOR') then + + GEOSgcm_defs(1:N_GEOSgcm_vars,:) = M21CCSCOR_defs(1:N_GEOSgcm_vars,:) + + else + + call ldas_abort(LDAS_GENERIC_ERROR, Iam, 'unknown "M21C[xxx]" met_tag') + + end if + + daily_met_files = .false. ! might change to daily upon public distribution? + + call parse_M21C_met_tag( met_path, met_tag, date_time_inst, & + met_path_inst, prec_path_inst, met_tag_inst, use_prec_corr ) + + call parse_M21C_met_tag( met_path, met_tag, date_time_fwd, & + met_path_fwd, prec_path_fwd, met_tag_fwd, use_prec_corr ) + + call parse_M21C_met_tag( met_path, met_tag, date_time_bkwd, & + met_path_bkwd, prec_path_bkwd, met_tag_bkwd, use_prec_corr ) + + elseif (met_tag(1:2)=='M2') then ! MERRA-2 select case (AEROSOL_DEPOSITION) @@ -3660,6 +3722,7 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & call parse_MERRA2_met_tag( met_path, met_tag, date_time_bkwd, & met_path_bkwd, prec_path_bkwd, met_tag_bkwd, use_prec_corr ) + else ! GEOS ADAS (FP) @@ -4689,6 +4752,161 @@ subroutine parse_MERRA2_met_tag( met_path_in, met_tag_in, date_time, & end subroutine parse_MERRA2_met_tag + ! **************************************************************** + + subroutine parse_M21C_met_tag( met_path_in, met_tag_in, date_time, & + met_path_default, met_path_prec, met_tag_out, use_prec_corr ) + + ! reichle, 15 Jan 2025 + + ! parse M21C "met_tag", extract M21C stream, assemble data paths + ! + ! met_tag = "M21C[CS][xxx]_[STREAM]{__prec[PREC]}" + ! + ! where {__prec[PREC]} is optional and where + ! + ! [xxx] = 'INT' or 'COR' + ! [CS] = cube-sphere forcing (optional; works only with matching c360 tile space for simulation) + ! [STREAM] = 'jan98', 'jan08', 'jan18', or 'cross' + ! [PREC] = indicates corrected precip dataset + ! + ! examples: + ! + ! STREAM = 'jan08' : use only Stream 2 M21C data + ! STREAM = 'cross' : integrate across more than one M21C stream + ! + ! --------------------------------------------------------------------------- + + implicit none + + character(*), intent(in) :: met_path_in + character(*), intent(in) :: met_tag_in + + type(date_time_type), intent(in) :: date_time + + character(200), intent(out) :: met_path_default, met_path_prec + character( 80), intent(out) :: met_tag_out + + logical, intent(out) :: use_prec_corr + + ! local variables + + integer :: is, tmpind + + type(date_time_type) :: dt1, dt2 + + character( 5) :: tmpstream + character(16) :: stream + character(80) :: prec_tag + + character(len=*), parameter :: Iam = 'parse_M21C_met_tag' + character(len=400) :: err_msg + + ! ---------------------------------------------------------- + + ! define intervals that determine which MERRA-2 stream is used + ! in integrations that "cross" multiple streams + ! + ! 1/1/1998 - 12/31/2007: e5303_m21c_jan98 (Stream 1) + ! 1/1/2008 - 12/31/2017: e5303_m21c_jan08 (Stream 2) + ! 1/1/2018 - present: e5303_m21c_jan18 (Stream 3) + + ! dates before dt1 use Stream 1 + + dt1%year = 2008 + dt1%month = 1 + dt1%day = 1 + dt1%hour = 0 + dt1%min = 0 + dt1%sec = 0 + + ! otherwise, dates before dt2 use Stream 2 + + dt2%year = 2018 + dt2%month = 1 + dt2%day = 1 + dt2%hour = 0 + dt2%min = 0 + dt2%sec = 0 + + ! ---------------------------------------------------- + + ! initialize + + met_tag_out = repeat(' ', len(met_tag_out)) + + stream = repeat(' ', len(stream )) + + ! define which stream to use + + tmpind = 9 + + if (met_tag_in(5:6) = 'CS') tmpind = tmpind + 2 + + tmpstream = met_tag_in(tmpind:tmpind+4) + + if (tmpstream=='cross') then + + if (datetime_lt_refdatetime( date_time, dt1 )) then + + tmpstream = 'jan98' + + elseif (datetime_lt_refdatetime( date_time, dt2 )) then + + tmpstream = 'jan08' + + else + + tmpstream = 'jan18' + + end if + + end if + + met_tag_out = 'e5303_m21c_' // tmpstream + + met_path_default = trim(met_path_in) // '/' + + ! ----------------------------------------------------- + ! + ! identify which precip corrections to use, + ! assemble met_path accordingly + ! + ! met_tag = "M21C[CS][xxx]_[STREAM]{__prec[PREC]}" + ! + ! where {__prec[PREC]} is optional + + is = index( met_tag_in, '__') + + if (is>0) then ! using precip corrections + + prec_tag = met_tag_in(is+6:len(met_tag_in)) + + met_path_prec = trim(met_path_in) // '/precip_corr_' // trim(prec_tag) // '/' + + use_prec_corr = .true. + + else ! not using precip corrections + + prec_tag = repeat(' ', len(prec_tag)) + + met_path_prec = met_path_default + + use_prec_corr = .false. + + ! check if prec_tag was accidentally appended with a single underscore + + if (len_trim(met_tag_in)>tmpind+6) then + + err_msg = 'questionable met_tag_in, not enough double underscores' + call ldas_abort(LDAS_GENERIC_ERROR, Iam, err_msg) + + end if + + end if + + end subroutine parse_M21C_met_tag + ! **************************************************************** subroutine parse_G5DAS_met_tag( met_path_in, met_tag_in, date_time, & @@ -5279,12 +5497,19 @@ subroutine get_GEOS_forcing_filename(fname_full,file_exists, date_time, daily_fi time_stamp(1:8) = YYYY // MM // DD - elseif (index(met_tag,'GEOSIT') > 0 .or. index(met_tag,'geosit') > 0) then + elseif ( & + index(met_tag,'GEOSIT') > 0 .or. index(met_tag,'geosit') > 0 & + index(met_tag,'M21C' ) > 0 .or. index(met_tag,'m21c' ) > 0 & + ) then + + ! newer time stamp format (GEOS-IT, M21C, ...) time_stamp(1:16) = YYYY //'-'// MM //'-'// DD // 'T' // trim(HHMM) // 'Z' - + else + ! old time stamp format (MERRA, MERRA-2, FP) + time_stamp(1:14) = YYYY // MM // DD // '_' // trim(HHMM) // 'z' end if From d224e6a70bd840e6e77d982e3ca25e628a56fe6a Mon Sep 17 00:00:00 2001 From: Rolf Reichle Date: Thu, 23 Jan 2025 11:39:55 -0500 Subject: [PATCH 3/5] fixing errors in previous commit (LDAS_Forcing.F90) --- GEOSmetforce_GridComp/LDAS_Forcing.F90 | 61 ++++++++++++++------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/GEOSmetforce_GridComp/LDAS_Forcing.F90 b/GEOSmetforce_GridComp/LDAS_Forcing.F90 index 5c7bca7..c2aeff1 100755 --- a/GEOSmetforce_GridComp/LDAS_Forcing.F90 +++ b/GEOSmetforce_GridComp/LDAS_Forcing.F90 @@ -3260,8 +3260,7 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & GEOSIT_defs = G5DAS_defs - ! GEOSIT character(40): - ! + ! character(40): ! 1 2 3 4 ! 1234567890123456789012345678901234567890 @@ -3305,18 +3304,22 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & M21CCSINT_defs = M21CINT_defs - M21CCSINT_defs( 1,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] - M21CCSINT_defs( 2,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] - M21CCSINT_defs( 3,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] - M21CCSINT_defs( 4,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] - M21CCSINT_defs( 5,3)=[character(len=40):: 'int_tavg_1hr_glo_C360x360x6_slv' ] ! uncorrected - M21CCSINT_defs( 6,3)=[character(len=40):: 'int_tavg_1hr_glo_C360x360x6_slv' ] ! uncorrected - M21CCSINT_defs( 7,3)=[character(len=40):: 'int_tavg_1hr_glo_C360x360x6_slv' ] ! uncorrected - M21CCSINT_defs( 8,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] - M21CCSINT_defs( 9,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] - M21CCSINT_defs(10,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] - M21CCSINT_defs(11,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] - M21CCSINT_defs(12,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + ! character(40): + ! 1 2 3 4 + ! 1234567890123456789012345678901234567890 + + M21CCSINT_defs( 1,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' + M21CCSINT_defs( 2,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' + M21CCSINT_defs( 3,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' + M21CCSINT_defs( 4,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' + M21CCSINT_defs( 5,3) = 'int_tavg_1hr_glo_C360x360x6_slv ' ! uncorrected + M21CCSINT_defs( 6,3) = 'int_tavg_1hr_glo_C360x360x6_slv ' ! uncorrected + M21CCSINT_defs( 7,3) = 'int_tavg_1hr_glo_C360x360x6_slv ' ! uncorrected + M21CCSINT_defs( 8,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' + M21CCSINT_defs( 9,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' + M21CCSINT_defs(10,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' + M21CCSINT_defs(11,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' + M21CCSINT_defs(12,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' ! M21C file specs with corrected precip, which could be either ! - native (ie, the precip seen by the land surface in the M21C system), or @@ -3338,18 +3341,22 @@ subroutine get_GEOS( date_time, force_dtstep, met_path, met_tag, & M21CCSCOR_defs = M21CCOR_defs - M21CCSCOR_defs( 1,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] - M21CCSCOR_defs( 2,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] - M21CCSCOR_defs( 3,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] - M21CCSCOR_defs( 4,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] - M21CCSCOR_defs( 5,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] ! M21C built-in corrections - M21CCSCOR_defs( 6,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] ! M21C built-in corrections - M21CCSCOR_defs( 7,3)=[character(len=40):: 'lfo_tavg_1hr_glo_C360x360x6_slv' ] ! M21C built-in corrections - M21CCSCOR_defs( 8,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] - M21CCSCOR_defs( 9,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] - M21CCSCOR_defs(10,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] - M21CCSCOR_defs(11,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] - M21CCSCOR_defs(12,3)=[character(len=40):: 'lfo_inst_1hr_glo_C360x360x6_slv' ] + ! character(40): + ! 1 2 3 4 + ! 1234567890123456789012345678901234567890 + + M21CCSCOR_defs( 1,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' + M21CCSCOR_defs( 2,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' + M21CCSCOR_defs( 3,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' + M21CCSCOR_defs( 4,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' + M21CCSCOR_defs( 5,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' ! M21C built-in corrections + M21CCSCOR_defs( 6,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' ! M21C built-in corrections + M21CCSCOR_defs( 7,3) = 'lfo_tavg_1hr_glo_C360x360x6_slv ' ! M21C built-in corrections + M21CCSCOR_defs( 8,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' + M21CCSCOR_defs( 9,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' + M21CCSCOR_defs(10,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' + M21CCSCOR_defs(11,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' + M21CCSCOR_defs(12,3) = 'lfo_inst_1hr_glo_C360x360x6_slv ' ! ----------------------------------------------------------------------- @@ -4841,7 +4848,7 @@ subroutine parse_M21C_met_tag( met_path_in, met_tag_in, date_time, & tmpind = 9 - if (met_tag_in(5:6) = 'CS') tmpind = tmpind + 2 + if (met_tag_in(5:6) == 'CS') tmpind = tmpind + 2 tmpstream = met_tag_in(tmpind:tmpind+4) From 5d40715c78642bbde7da92714421339b3e0db29a Mon Sep 17 00:00:00 2001 From: Rolf Reichle Date: Thu, 23 Jan 2025 12:15:36 -0500 Subject: [PATCH 4/5] fixing another syntax error in previous commit (LDAS_Forcing.F90) --- GEOSmetforce_GridComp/LDAS_Forcing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GEOSmetforce_GridComp/LDAS_Forcing.F90 b/GEOSmetforce_GridComp/LDAS_Forcing.F90 index c2aeff1..6ac6a58 100755 --- a/GEOSmetforce_GridComp/LDAS_Forcing.F90 +++ b/GEOSmetforce_GridComp/LDAS_Forcing.F90 @@ -5504,9 +5504,9 @@ subroutine get_GEOS_forcing_filename(fname_full,file_exists, date_time, daily_fi time_stamp(1:8) = YYYY // MM // DD - elseif ( & - index(met_tag,'GEOSIT') > 0 .or. index(met_tag,'geosit') > 0 & - index(met_tag,'M21C' ) > 0 .or. index(met_tag,'m21c' ) > 0 & + elseif ( & + index(met_tag,'GEOSIT') > 0 .or. index(met_tag,'geosit') > 0 .or. & + index(met_tag,'M21C' ) > 0 .or. index(met_tag,'m21c' ) > 0 & ) then ! newer time stamp format (GEOS-IT, M21C, ...) From f930ece2fb18806b278c59339cdc50e1fe6362e6 Mon Sep 17 00:00:00 2001 From: Rolf Reichle Date: Fri, 24 Jan 2025 16:17:37 -0500 Subject: [PATCH 5/5] added clarification to "sample exe input" file about requirement of matching cs tile space when using surface met forcing on cs grid (ldas_setup) --- GEOSldas_App/ldas_setup | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/GEOSldas_App/ldas_setup b/GEOSldas_App/ldas_setup index 0c495d8..dfbe28e 100755 --- a/GEOSldas_App/ldas_setup +++ b/GEOSldas_App/ldas_setup @@ -1504,6 +1504,11 @@ def _printExeInputKeys(rqdExeInpKeys): print ('# #') print ('# Surface meteorological forcing time step is in seconds. #') print ('# #') + print ('# NOTE: #') + print ('# When forcing is on cube-sphere (CS) grid, must use: #') + print ('# - Model tile space (BCS) derived from same CS grid. #') + print ('# - Nearest-neighbor interpolation (MET_HINTERP: 0). #') + print ('# #') print ('# For more information, see: #') print ('# GEOSldas/doc/README.MetForcing_and_BCS.md #') print ('# #')