From 06a2f79c141c760eb1f61e2a62fecce630bff499 Mon Sep 17 00:00:00 2001 From: Yeosang Yoon Date: Wed, 24 Jan 2024 14:17:08 -0500 Subject: [PATCH 1/8] update codes for precpitation bias-correction --- lis/metforcing/mogreps_g/get_cdf_params.F90 | 209 ++++++++++++++++++ lis/metforcing/mogreps_g/get_mogrepsg.F90 | 48 +++- .../mogreps_g/mogrepsg_forcingMod.F90 | 34 ++- lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 | 18 ++ .../mogreps_g/timeinterp_mogrepsg.F90 | 23 +- 5 files changed, 325 insertions(+), 7 deletions(-) create mode 100644 lis/metforcing/mogreps_g/get_cdf_params.F90 diff --git a/lis/metforcing/mogreps_g/get_cdf_params.F90 b/lis/metforcing/mogreps_g/get_cdf_params.F90 new file mode 100644 index 000000000..7baec6b5f --- /dev/null +++ b/lis/metforcing/mogreps_g/get_cdf_params.F90 @@ -0,0 +1,209 @@ +!-----------------------BEGIN NOTICE -- DO NOT EDIT----------------------- +! NASA Goddard Space Flight Center +! Land Information System Framework (LISF) +! Version 7.3 +! +! Copyright (c) 2020 United States Government as represented by the +! Administrator of the National Aeronautics and Space Administration. +! All Rights Reserved. +!-------------------------END NOTICE -- DO NOT EDIT----------------------- +#include "LIS_misc.h" +!BOP +! +! !ROUTINE: get_cdf_params +! \label{get_cdf_params} +! +! !REVISION HISTORY: +! 01 May 2023: Yeosang Yoon, initial code +! +! !INTERFACE: +subroutine get_cdf_params (n, fname, month, param_a, param_b, mean, std) + + !USES: + use LIS_coreMod + use LIS_logMod + use mogrepsg_forcingMod, only : mogrepsg_struc +#if (defined USE_NETCDF3 || defined USE_NETCDF4) + use netcdf +#endif + + implicit none + + !ARGUMENTS: + integer, intent(in) :: n + character(len=*), intent(in) :: fname + integer, intent(in) :: month ! month of year (1-12) + + !EOP + logical :: file_exists + integer :: ftn + integer :: param_a_id, param_b_id, mean_id, std_id, ngrid_id, nlead_id + integer :: ngrid, nlead + integer :: r, c, nc, c1, r1, gid, l + real,allocatable :: param_hires(:,:) + real,allocatable :: param_hires_2d(:,:) + real :: param_a(LIS_rc%ngrid(n),8) !8: lead time + real :: param_b(LIS_rc%ngrid(n),8) + real :: mean(LIS_rc%ngrid(n),8) + real :: std(LIS_rc%ngrid(n),8) + + ! check file + inquire(file=fname, exist=file_exists) + if(.not. file_exists) then + write(LIS_logunit,*) '[ERR] ',trim(fname)//' does not exist' + call LIS_endrun() + endif + + write(LIS_logunit,*)'[INFO] Getting MOGREPS-G bias correction parameters ', trim(fname) + call LIS_verify(nf90_open(path=trim(fname), mode=NF90_NOWRITE, & + ncid=ftn), 'nf90_open failed in get_cdf_params') + + call LIS_verify(nf90_inq_dimid(ftn, "ngrid", ngrid_id), & + 'nf90_inq_dimid failed for ngrid in get_cdf_params') + call LIS_verify(nf90_inquire_dimension(ftn, ngrid_id, len=ngrid),& + 'nf90_inquire_dimension failed for ngrid in get_cdf_params') + + if(LIS_rc%gnc(n)*LIS_rc%gnr(n) .ne. ngrid) then + write(LIS_logunit,*) 'The input dimensions of the '//trim(fname) + write(LIS_logunit,*) '(',ngrid,')' + write(LIS_logunit,*) 'does not match the dimensions in the LIS parameter file' + write(LIS_logunit,*) '(',LIS_rc%gnc(n)*LIS_rc%gnr(n),')' + call LIS_endrun() + endif + + call LIS_verify(nf90_inq_dimid(ftn, "lead_time", nlead_id), & + 'nf90_inq_dimid failed for nlead in get_cdf_params') + call LIS_verify(nf90_inquire_dimension(ftn, nlead_id, len=nlead),& + 'nf90_inquire_dimension failed for nlead in get_cdf_params') + + allocate(param_hires(LIS_rc%gnc(n)*LIS_rc%gnr(n),nlead)) + allocate(param_hires_2d(LIS_rc%gnc(n),LIS_rc%gnr(n))) + + param_hires = -9999.0 + param_hires_2d = -9999.0 + + ! read param_a + call LIS_verify(nf90_inq_varid(ftn,'cdf_param_a',param_a_id), & + 'nf90_inq_varid failed for cdf_param_a in get_cdf_params') + call LIS_verify(nf90_get_var(ftn, param_a_id, param_hires, & + start=(/1,1,month/), count=(/ngrid,nlead,1/)),& + 'nf90_get_var failed for cdf_param_a in get_cdf_params') + + do l=1,nlead + ! 1D -> 2D + do r=1,LIS_rc%gnr(n) + do c=1,LIS_rc%gnc(n) + param_hires_2d(c,r)=param_hires(c+(r-1)*LIS_rc%gnc(n),l) + enddo + enddo + + !subsets the data for each processor's domain + nc = (LIS_ewe_halo_ind(n,LIS_localPet+1)-LIS_ews_halo_ind(n,LIS_localPet+1))+1 + do r=LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) + do c=LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) + c1 = c-LIS_ews_halo_ind(n,LIS_localPet+1)+1 + r1 = r-LIS_nss_halo_ind(n,LIS_localPet+1)+1 + gid = LIS_domain(n)%gindex(c1,r1) + if(gid.ne.-1) then + param_a(gid,l) = param_hires_2d(c,r) + endif + enddo + enddo + enddo + + ! read param_b + call LIS_verify(nf90_inq_varid(ftn,'cdf_param_b',param_b_id), & + 'nf90_inq_varid failed for cdf_param_b in get_cdf_params') + call LIS_verify(nf90_get_var(ftn, param_b_id, param_hires, & + start=(/1,1,month/), count=(/ngrid,nlead,1/)),& + 'nf90_get_var failed for cdf_param_b in get_cdf_params') + + do l=1,nlead + ! 1D -> 2D + do r=1,LIS_rc%gnr(n) + do c=1,LIS_rc%gnc(n) + param_hires_2d(c,r)=param_hires(c+(r-1)*LIS_rc%gnc(n),l) + enddo + enddo + + !subsets the data for each processor's domain + nc = (LIS_ewe_halo_ind(n,LIS_localPet+1)-LIS_ews_halo_ind(n,LIS_localPet+1))+1 + do r=LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) + do c=LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) + c1 = c-LIS_ews_halo_ind(n,LIS_localPet+1)+1 + r1 = r-LIS_nss_halo_ind(n,LIS_localPet+1)+1 + gid = LIS_domain(n)%gindex(c1,r1) + if(gid.ne.-1) then + param_b(gid,l) = param_hires_2d(c,r) + endif + enddo + enddo + enddo + + ! read mean + call LIS_verify(nf90_inq_varid(ftn,'mean',mean_id), & + 'nf90_inq_varid failed for mean in get_cdf_params') + call LIS_verify(nf90_get_var(ftn, mean_id, param_hires, & + start=(/1,1,month/), count=(/ngrid,nlead,1/)),& + 'nf90_get_var failed for mean in get_cdf_params') + + do l=1,nlead + ! 1D -> 2D + do r=1,LIS_rc%gnr(n) + do c=1,LIS_rc%gnc(n) + param_hires_2d(c,r)=param_hires(c+(r-1)*LIS_rc%gnc(n),l) + enddo + enddo + + !subsets the data for each processor's domain + nc = (LIS_ewe_halo_ind(n,LIS_localPet+1)-LIS_ews_halo_ind(n,LIS_localPet+1))+1 + do r=LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) + do c=LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) + c1 = c-LIS_ews_halo_ind(n,LIS_localPet+1)+1 + r1 = r-LIS_nss_halo_ind(n,LIS_localPet+1)+1 + gid = LIS_domain(n)%gindex(c1,r1) + if(gid.ne.-1) then + mean(gid,l) = param_hires_2d(c,r) + endif + enddo + enddo + enddo + + ! read std + call LIS_verify(nf90_inq_varid(ftn,'std',std_id), & + 'nf90_inq_varid failed for std in get_cdf_params') + call LIS_verify(nf90_get_var(ftn, std_id, param_hires, & + start=(/1,1,month/), count=(/ngrid,nlead,1/)),& + 'nf90_get_var failed for std in get_cdf_params') + + do l=1,nlead + ! 1D -> 2D + do r=1,LIS_rc%gnr(n) + do c=1,LIS_rc%gnc(n) + param_hires_2d(c,r)=param_hires(c+(r-1)*LIS_rc%gnc(n),l) + enddo + enddo + + !subsets the data for each processor's domain + nc = (LIS_ewe_halo_ind(n,LIS_localPet+1)-LIS_ews_halo_ind(n,LIS_localPet+1))+1 + do r=LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) + do c=LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) + c1 = c-LIS_ews_halo_ind(n,LIS_localPet+1)+1 + r1 = r-LIS_nss_halo_ind(n,LIS_localPet+1)+1 + gid = LIS_domain(n)%gindex(c1,r1) + if(gid.ne.-1) then + std(gid,l) = param_hires_2d(c,r) + endif + enddo + enddo + enddo + + deallocate(param_hires) + deallocate(param_hires_2d) + + call LIS_verify(nf90_close(ftn),'failed to close in get_cdf_params') + + write(LIS_logunit,*) 'Done reading MOGREPS-G bias correction parameters data ' + +end subroutine get_cdf_params + diff --git a/lis/metforcing/mogreps_g/get_mogrepsg.F90 b/lis/metforcing/mogreps_g/get_mogrepsg.F90 index 7f4169c3e..9877b0599 100644 --- a/lis/metforcing/mogreps_g/get_mogrepsg.F90 +++ b/lis/metforcing/mogreps_g/get_mogrepsg.F90 @@ -16,6 +16,7 @@ ! !REVISION HISTORY: ! 26 Jan 2023: Yeosang Yoon, initial code ! 13 Mar 2023: Yeosang Yoon, update codes to fit new format +! 01 Jan 2024; Yeosang Yoon; update codes for precpi. bias-correction ! ! !INTERFACE: subroutine get_mogrepsg(n, findex) @@ -43,7 +44,7 @@ subroutine get_mogrepsg(n, findex) ! the current model timestep. !EOP - integer :: order, ferror, m + integer :: order, ferror, m, t character(len=LIS_CONST_PATH_LEN) :: fname integer :: yr1, mo1, da1, hr1, mn1, ss1, doy1 integer :: yr2, mo2, da2, hr2, mn2, ss2, doy2 @@ -55,6 +56,10 @@ subroutine get_mogrepsg(n, findex) integer :: fcsthr_intv integer :: openfile + ! precipitation bias correction + real :: pcp1, pcp2 + integer :: lead_time + external :: get_mogrepsg_filename external :: read_mogrepsg @@ -172,6 +177,47 @@ subroutine get_mogrepsg(n, findex) mogrepsg_struc(n)%metdata2(4,m,:) = mogrepsg_struc(n)%metdata1(4,m,:) endif endif + + ! apply precipitation bias correction (cdf from difference bewteen NAPFA and MOGREPS-G) + if (mogrepsg_struc(n)%bc == 1) then + lead_time=floor((float(mogrepsg_struc(n)%fcst_hour))/24)+1 + + if (lead_time > 8) then + lead_time = 8 + endif + + do t=1, LIS_rc%ngrid(n) + if(mogrepsg_struc(n)%metdata2(8,m,t).ne.LIS_rc%udef) then + ! only for land pixels + if (mogrepsg_struc(n)%bc_param_a(t,lead_time) .ne. LIS_rc%udef) then + ! perform centering and scaling + pcp1=mogrepsg_struc(n)%metdata2(8,m,t)-mogrepsg_struc(n)%metdata1(8,m,t) + if (mogrepsg_struc(n)%bc_std(t,lead_time) .ne. 0) then + pcp2=(pcp1-mogrepsg_struc(n)%bc_mean(t,lead_time))/& + mogrepsg_struc(n)%bc_std(t,lead_time) + else + pcp2=pcp1 + endif + + ! apply cdf params + pcp2=pcp2*mogrepsg_struc(n)%bc_param_a(t,lead_time)+mogrepsg_struc(n)%bc_param_b(t,lead_time) + ! check for negative precipitation; if the corrected value has negative, keep the original value. + if(pcp2 >= 0) then + mogrepsg_struc(n)%pcp_bc(m,t)=pcp2 + else + mogrepsg_struc(n)%pcp_bc(m,t)=pcp1 + endif + ! additionally, avoid bias correction for values that are too samll to reduce abnormal noise. + if(pcp1 < 0.01) then + mogrepsg_struc(n)%pcp_bc(m,t)=pcp1 + endif + else ! for water pixels + mogrepsg_struc(n)%pcp_bc(m,t)=mogrepsg_struc(n)%metdata2(8,m,t)-mogrepsg_struc(n)%metdata1(8,m,t) + endif + endif + enddo + endif + enddo endif openfile=0 diff --git a/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 b/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 index 180162578..e90cb40b5 100644 --- a/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 +++ b/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 @@ -19,6 +19,7 @@ module mogrepsg_forcingMod ! REVISION HISTORY: ! 26 Jan 2023; Yeosang Yoon; Initial Specification +! 01 Jan 2024; Yeosang Yoon; update codes for precpi. bias-correction ! !USES: use LIS_constantsMod, only : LIS_CONST_PATH_LEN @@ -89,6 +90,15 @@ module mogrepsg_forcingMod integer, allocatable :: nv113(:) + ! precipitation bias correction + integer :: bc !option for bias correction + character(len=LIS_CONST_PATH_LEN) :: cdf_fname !MOGREPS-G model CDF file name + real, allocatable :: pcp_bc(:,:) + real, allocatable :: bc_param_a(:,:) + real, allocatable :: bc_param_b(:,:) + real, allocatable :: bc_mean(:,:) + real, allocatable :: bc_std(:,:) + end type mogrepsg_type_dec type(mogrepsg_type_dec), allocatable :: mogrepsg_struc(:) @@ -160,7 +170,7 @@ subroutine init_mogrepsg(findex) ! Check if starting hour of LIS run matches 00/06/12/18 UTC: if((LIS_rc%shr .ne. 0) .and. (LIS_rc%shr .ne. 6) .and. & (LIS_rc%shr .ne. 12) .and. (LIS_rc%shr .ne. 18)) then - write(LIS_logunit,*) "[ERR] GALWEM forecast type begins" + write(LIS_logunit,*) "[ERR] MOGREPS-G forecast type begins" write(LIS_logunit,*) "[ERR] at 00/12Z for a forecast window, so the " write(LIS_logunit,*) "[ERR] 'Starting hour:' should be set to 0/12 in" write(LIS_logunit,*) "[ERR] your lis.config file.." @@ -340,5 +350,27 @@ subroutine init_mogrepsg(findex) endif enddo + ! precipitation bias correction + do n=1,LIS_rc%nnest + if (mogrepsg_struc(n)%bc == 1) then + allocate(mogrepsg_struc(n)%pcp_bc(mogrepsg_struc(n)%max_ens_members,LIS_rc%ngrid(n))) + allocate(mogrepsg_struc(n)%bc_param_a(LIS_rc%ngrid(n),8)) !8: lead time + allocate(mogrepsg_struc(n)%bc_param_b(LIS_rc%ngrid(n),8)) + allocate(mogrepsg_struc(n)%bc_mean(LIS_rc%ngrid(n),8)) + allocate(mogrepsg_struc(n)%bc_std(LIS_rc%ngrid(n),8)) + + mogrepsg_struc(n)%pcp_bc = 0 + mogrepsg_struc(n)%bc_param_a = 0 + mogrepsg_struc(n)%bc_param_b = 0 + mogrepsg_struc(n)%bc_mean = 0 + mogrepsg_struc(n)%bc_std = 0 + + ! read cdf parameters + call get_cdf_params(n,mogrepsg_struc(n)%cdf_fname,LIS_rc%mo,& + mogrepsg_struc(n)%bc_param_a, mogrepsg_struc(n)%bc_param_b,& + mogrepsg_struc(n)%bc_mean, mogrepsg_struc(n)%bc_std) + endif + enddo + end subroutine init_mogrepsg end module mogrepsg_forcingMod diff --git a/lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 b/lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 index 07777f8f6..0ab191a4a 100644 --- a/lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 +++ b/lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 @@ -14,6 +14,7 @@ ! ! !REVISION HISTORY: ! 26 Jan 2023; Yeosang Yoon, Initial Code +! 01 Jan 2024; Yeosang Yoon; update codes for precpi. bias-correction ! ! !INTERFACE: subroutine readcrd_mogrepsg() @@ -52,11 +53,28 @@ subroutine readcrd_mogrepsg() call ESMF_ConfigGetAttribute(LIS_config,mogrepsg_struc(n)%max_ens_members,rc=rc) enddo + call ESMF_ConfigFindLabel(LIS_config,"Apply MOGREPS-G precipitation bias correction:",rc=rc) + call LIS_verify(rc, 'Apply MOGREPS-G precipitation bias correction: not defined') + do n=1,LIS_rc%nnest + call ESMF_ConfigGetAttribute(LIS_config,mogrepsg_struc(n)%bc,rc=rc) + enddo + + call ESMF_ConfigFindLabel(LIS_config,"MOGREPS-G model CDF file:",rc=rc) + call LIS_verify(rc, 'MOGREPS-G model CDF file: not defined') + do n=1,LIS_rc%nnest + call ESMF_ConfigGetAttribute(LIS_config,mogrepsg_struc(n)%cdf_fname,rc=rc) + enddo + do n=1,LIS_rc%nnest write(LIS_logunit,*) '[INFO] Using MOGREPS-G forecast forcing' write(LIS_logunit,*) '[INFO] MOGREPS-G forecast forcing directory: ', trim(mogrepsg_struc(n)%odir) write(LIS_logunit,*) '[INFO] MOGREPS-G forecast run mode: ',mogrepsg_struc(n)%runmode write(LIS_logunit,*) '[INFO] MOGREPS-G forecast number of ensemble members:',& mogrepsg_struc(n)%max_ens_members + write(LIS_logunit,*) '[INFO] Using MOGREPS-G precipitation bias correction:',& + mogrepsg_struc(n)%bc + if (mogrepsg_struc(n)%bc == 1) then + write(LIS_logunit,*) '[INFO] MOGREPS-G model CDF file: ', trim(mogrepsg_struc(n)%cdf_fname) + endif enddo end subroutine readcrd_mogrepsg diff --git a/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 b/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 index 846260b0f..efb0b4d8f 100644 --- a/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 +++ b/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 @@ -15,6 +15,7 @@ ! !REVISION HISTORY: ! ! 26 Jan 2023: Yeosang Yoon, Initial specification +! 01 Jan 2024; Yeosang Yoon; update codes for precpi. bias-correction ! ! !INTERFACE: subroutine timeinterp_mogrepsg(n,findex) @@ -239,13 +240,25 @@ subroutine timeinterp_mogrepsg(n,findex) tid = (t-1)*LIS_rc%nensem(n)+(m-1)*mfactor+k index1 = LIS_domain(n)%tile(tid)%index - if(mogrepsg_struc(n)%metdata2(8,m,index1).ne.LIS_rc%udef) then - ! account for the accum fields - pcp(tid)=(mogrepsg_struc(n)%metdata2(8,m,index1)-mogrepsg_struc(n)%metdata1(8,m,index1))/real(3600*3) - if(pcp(tid).lt.0) then - pcp(tid) = 0.0 + ! apply precipitation bias correction + if (mogrepsg_struc(n)%bc == 1) then !1 - use; or 0 + if(mogrepsg_struc(n)%pcp_bc(m,index1).ne.LIS_rc%udef) then + ! account for the accum fields + pcp(tid)=mogrepsg_struc(n)%pcp_bc(m,index1)/(3600*3) + if(pcp(tid).lt.0) then + pcp(tid) = 0.0 + endif + endif + else !don't apply bias correction + if(mogrepsg_struc(n)%metdata2(8,m,index1).ne.LIS_rc%udef) then + ! account for the accum fields + pcp(tid)=(mogrepsg_struc(n)%metdata2(8,m,index1)-mogrepsg_struc(n)%metdata1(8,m,index1))/(3600*3) + if(pcp(tid).lt.0) then + pcp(tid) = 0.0 + endif endif endif + enddo enddo enddo From 432b127f0081b8b509a94ee373eea4afe9f930be Mon Sep 17 00:00:00 2001 From: Yeosang Yoon Date: Fri, 26 Jan 2024 14:10:33 -0500 Subject: [PATCH 2/8] update lis.config.adoc --- lis/configs/lis.config.adoc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lis/configs/lis.config.adoc b/lis/configs/lis.config.adoc index c775615a8..031d04caf 100644 --- a/lis/configs/lis.config.adoc +++ b/lis/configs/lis.config.adoc @@ -6559,7 +6559,7 @@ MRMS mask directory: ./input/MASKS/ AWRAL forcing directory: ./INPUT/AWRAL.FORCING AWRAL domain x-dimension size: 841 AWRAL domain y-dimension size: 681 -.... +...` specifies the . [[sssec_plumber2forcing,PLUMBER2]] ==== PLUMBER2 @@ -6650,11 +6650,25 @@ run mode. Currently, only the forecast mode is supported. `MOGREPS-G forecast number of ensemble members:` specifies the number of ensembles of the MOGREPS-G forecast forcing data. +`Apply MOGREPS-G precipitation bias correction:` specifies whether to enable the +precipitation bias correction. Acceptable values are: + +|==== +|Value | Description + +|0 | Do not enable +|1 | Enable +|==== + +`MOGREPS-G model CDF file:` specifies the location of the MOGREPS-G model CDF file. + .Example _lis.config_ entry .... MOGREPS-G forecast forcing directory: ./MOGREPS-G MOGREPS-G forecast run mode: forecast # forecast | analysis MOGREPS-G forecast number of ensemble members: 18 +Apply MOGREPS-G precipitation bias correction: 1 #enter 1 - use; or 0 +MOGREPS-G model CDF file: ./input/cdf/MOGREPS_G_leadtime_cdf_10km.nc .... [[ssec_lsm,Land surface models]] From 90f91f69697e707a88f944d709257e9bf454b79f Mon Sep 17 00:00:00 2001 From: Yeosang Yoon Date: Fri, 26 Jan 2024 14:18:13 -0500 Subject: [PATCH 3/8] fix lis.config.adoc --- lis/configs/lis.config.adoc | 239 ++---------------------------------- 1 file changed, 10 insertions(+), 229 deletions(-) diff --git a/lis/configs/lis.config.adoc b/lis/configs/lis.config.adoc index 031d04caf..3f9ed1881 100644 --- a/lis/configs/lis.config.adoc +++ b/lis/configs/lis.config.adoc @@ -189,33 +189,6 @@ Land surface model: Noah.2.7.1 .... -`Number of subLSMs:` specifies the number of sub-level LSMs -or specialized models that may interface with other LSMs in LIS. -Entry here can be set to 1 with having a surface model type -specified, such as "LSM", and set to 1. - -.Example _lis.config_ entry -.... -Number of subLSMs: 1 -.... - -`subLSM models:` specifies the sub-level land surface model to run. -Acceptable values are: - -|==== -|Value | Description - -|none | template lsm -|Crocus8.1 | Crocus version 8.1 snow model -|SnowModel | Glen Liston's SnowModel snow model -|==== - -.Example _lis.config_ entry -.... -subLSM models: "Crocus8.1" -.... - - `Lake model:` specifies the lake model to run. Acceptable values are: @@ -351,7 +324,6 @@ Acceptable values for the sources are: |"`GLDAS`" | GLDAS |"`GFS`" | GFS |"`MERRA2`" | MERRA2 -|"`GEOS-IT`" | GEOS-IT |"`CMAP`" | CMAP |"`TRMM 3B42RT`" | TRMM 3B42RT |"`TRMM 3B42RTV7`" | TRMM 3B42RTV7 @@ -414,8 +386,6 @@ Acceptable values are: |"`none`" | Do not apply topographic correction for forcing |"`lapse-rate`" | Use lapse rate correction for forcing |"`slope-aspect`" | Apply slope-aspect correction for forcing -|"`lapse-rate and slope-aspect`" | Apply both lapse-rate and slope-aspect corrections -|"`micromet`" | Apply Glen Liston's MicroMet corrections to forcing fields |==== .Example _lis.config_ entry @@ -666,18 +636,6 @@ AGRMET area of data: GLOBAL .... ==== -`Number of dimensions in the lat/lon output fields:` specifies the number of dimensions to use when writing the latitude and longitude fields of the LIS output. This is an optional entry. If this entry is not used, LIS will attempt to write the lat/lon fields in 1D. If the projection being used is not compatible with 1D, LIS will write in 2D. -Acceptable values are: -|==== -|Value | Description -|"1D" | 1 dimensional latitude and longitude output - (Note: Only the latlon projection supports 1D output) -|"2D" | 2 dimensional latitude and longitude output -|==== -.Example _lis.config_ entry -.... -Number of dimensions in the lat/lon output fields: "1D" -.... `Enable output statistics:` specifies whether to write the ASCII statistics file for the output data. @@ -3062,12 +3020,10 @@ whether the observation error standard deviation is to be scaled using model and observation standard deviation. `SMAP(NASA) model CDF file:` specifies the name of the model CDF file -(observations will be scaled into this climatology). -Note: Soil moisture CDF grouped (stratified) by land cover or precipitation climatology or both simultaneously also can be used here. +(observations will be scaled into this climatology). `SMAP(NASA) observation CDF file:` specifies the name of the observation CDF file. -Note: Soil moisture CDF grouped (stratified) by land cover or precipitation climatology or both simultaneously also can be used here. `SMAP(NASA) soil moisture number of bins in the CDF:` specifies the number of bins in the CDF. @@ -3143,33 +3099,6 @@ SMAP(NRT) CDF read option: .... -[[sssec_cdftransfersmda,Transfering stratified CDFs from one domain to another]] -==== Transfering stratified CDFs from one domain to another - -`Use CDF transfer for soil moisture data assimilation:` specifies -whether to use CDF transfer method. - -`Reference domain model CDF file:` specifies the reference domain model CDF name and data directory. - -`Reference domain obs CDF file:` specifies the reference domain obs CDF name and data directory. - -`Number of bins in the soil moisture CDF:` specifies the number of bins in the CDF. - -`Reference domain precipitation climatology data source:` specifies the reference domain precipitation climatology generated by LVT. - -`Target domain precipitation climatology data source:` specifies the target domain precipitation climatology generated by LVT. - - -.Example _lis.config_ entry -.... -Use CDF transfer for soil moisture data assimilation: -Reference domain model CDF file: ref_model_cdf_forcing_diff/stratified_cdf_noahmp401.nc -Reference domain obs CDF file: ref_obs_cdf_forcing_diff/stratified_cdf_smapobs.nc -Number of bins in the soil moisture CDF: 100 -Reference domain precipitation climatology data source: Precip.climo.us.nldas2/LVT_MEAN_FINAL.202201010000.d01.nc -Target domain precipitation climatology data source: Precip.climo.eu.merra/LVT_MEAN_FINAL.202201010000.d01.nc -.... - [[sssec_smapnasavodda,SMAP (NASA) vegetation optical depth assimilation]] ==== SMAP (NASA) vegetation optical depth assimilation @@ -5649,6 +5578,7 @@ GFS domain y-dimension size: 256 GFS number of forcing variables: 10 .... + [[sssec_forcings_MERRA2,MERRA2]] ==== MERRA2 @@ -5704,50 +5634,6 @@ MERRA2 use 2m wind fields: 0 MERRA2 use corrected total precipitation: 1 .... -[[sssec_forcings_GEOS-IT,GEOS-IT]] -==== GEOS-IT - -`GEOS-IT forcing directory:` specifies the location of -the GEOS-IT forcing files. - -Please note that GEOS-IT is currently in production and is -not complete for all calendar years. Also, it is not yet -available outside of NASA`'s NCCS computing platforms. -Also, the topographic or elevation correction option is -supported through the MERRA-2 geopotential terrain height -file. Please also see the latest LDT notes for updates on -how to use this option. - -`GEOS-IT use lowest model level forcing:` specifies whether -to use the lowest model level forcing. -Acceptable values are: - -|==== -|Value | Description - -|0 | Do not use the lowest model level forcing. -|1 | Use the lowest model level forcing. -|==== - -`GEOS-IT use 2m wind fields:` specifies whether to use the -2m diagnosed wind fields. This option will only work if -the lowest model level forcing option is turned off. -Acceptable values are: - -|==== -|Value | Description - -|0 | Do not use the 2m diagnosed wind speed fields. -|1 | Use the 2m diagnosed wind speed fields. -|==== - -.Example _lis.config_ entry -.... -GEOS-IT forcing directory: ./GEOS-IT -GEOS-IT use lowest model level forcing: 1 -GEOS-IT use 2m wind fields: 0 -.... - [[sssec_forcings_ERA5,ERA5]] ==== ERA5 @@ -6002,18 +5888,8 @@ default to the "`final`" product of GPM IMERG. `IMERG version:` specifies the version of the GPM IMERG precipitation forcing files. If no version is specified, -the reader will default to "`V06B`". - -The supported versions of GPM IMERG are: - -|==== -|Version | Product - -|V06B | early, late, final -|V06C | early, late, final -|V06D | early, late, final -|V07A | preliminary support for final -|==== +the reader will default to the latest version of GPM IMERG. +(Currently V06B). .Example _lis.config_ entry .... @@ -6559,7 +6435,7 @@ MRMS mask directory: ./input/MASKS/ AWRAL forcing directory: ./INPUT/AWRAL.FORCING AWRAL domain x-dimension size: 841 AWRAL domain y-dimension size: 681 -...` specifies the . +.... [[sssec_plumber2forcing,PLUMBER2]] ==== PLUMBER2 @@ -6650,8 +6526,8 @@ run mode. Currently, only the forecast mode is supported. `MOGREPS-G forecast number of ensemble members:` specifies the number of ensembles of the MOGREPS-G forecast forcing data. -`Apply MOGREPS-G precipitation bias correction:` specifies whether to enable the -precipitation bias correction. Acceptable values are: +`Apply MOGREPS-G precipitation bias correction:` specifies whether to enable the precipitation +bias correction. Acceptable values are: |==== |Value | Description @@ -6660,7 +6536,7 @@ precipitation bias correction. Acceptable values are: |1 | Enable |==== -`MOGREPS-G model CDF file:` specifies the location of the MOGREPS-G model CDF file. +`MOGREPS-G model CDF file:` specifies the location of the MOGREPS-G model CDF file. .Example _lis.config_ entry .... @@ -9673,103 +9549,6 @@ AWRAL600 initial sd: 0.5 0.5 AWRAL600 initial mleaf: 0.67 0.2 .... - -[[ssec_sublsm,Sublevel land surface models]] -=== Sublevel land surface models - - -[[sssec_sublsm_snowmodel,SnowModel]] -==== SnowModel, Liston - -`SnowModel model timestep:` specifies the timestep for the run. - -See Section <> for a description -of how to specify a time interval. - -`SnowModel restart output interval:` defines the restart -writing interval for Glen Liston's SnowModel model. The typical -value used in the LIS runs is 24 hours (1da). - -See Section <> for a description -of how to specify a time interval. - -`SnowModel restart file:` specifies the SnowModel active -restart file. - -`SnowModel restart file format:` specifies the restart file -format for SnowModel. - -`SnowModel parameter file:` specifies the main SnowModel-specific -input and option parameter configuration file, which is needed -to run SnowModel. - -`SnowModel parameters source option:` specifies if SnowModel will -read in its native binary parameter files from within the SnowModel -code or what is preprocessed in LDT. LDT option supports parallel runs -Acceptable values are: - -|==== -|Value | Description - -|SnowModel | Use SnowModel built-in routines to read in -|LDT | Use the LIS SnowModel main driver to load parameters from LDT. -|==== - -`SnowModel MicroMet input source:` specifies if SnowModel will -read in its own specifically formatted binary or ASCII table forcing -files, or if LIS meteorological forcing fields will be passed in, -with the option to turn on MicroMet topographic-downscaling options -on the LIS metforcing layer side. To turn on "micromet" option in LIS, -set Topographic correction method (met forcing) to micromet. -Acceptable values are: - -|==== -|Value | Description - -|SnowModel | Readin specific SnowModel forcing files -|LIS | LIS-based meteorological forcing fields -|==== - -`SnowModel preprocess code option:` specifies the turning on -of the SnowModel built-in preprocess code module, which performs -initial preprocessing of gridded data for running the model. -Currently, only option supported is 1 (on). - -`Write out SnowModel forcing file fields:` specifies if you -want to write out SnowModel forcing fields generated by reading -in SnowModel-specific forcing files. This option is mainly -used when SnowModel MicroMet input source is set to SnowModel -and you run SnowModel in offline subLSM mode (no other LSMs or models -run with this submodel). Selecting 1 activates this option, and -0 indicates off. - -`SnowModel number of snow layers:` specifies the number of snow -layers that would be allowed to build within the SnowModel runtime. -This option is currently set to 1 within LIS, and must also be -activated and increased by setting the multiple layer snow model -scheme in the SnowModel option parameter file (snowmodel.par). - -`SnowModel initial snow water equivalent:` specifies the initial -snow water equivalent (SWE) value. This is currently set to -default values found in the coldstart mode for model restart reads, -based on a SnowModel initialization approach. - -.Example _lis.config_ entry -.... -SnowModel model timestep: 1hr -SnowModel restart file: ./none -SnowModel restart output interval: 1mo -SnowModel restart file format: "netcdf" -SnowModel parameter file: ./snowmodel.par -SnowModel parameters source option: LDT -SnowModel MicroMet input source: LIS -Write out SnowModel forcing file fields: 1 -SnowModel preprocess code option: 1 -SnowModel number of snow layers: 1 -SnowModel initial snow water equivalent: 0.0 -.... - - [[ssec_lakes,Lake models]] === Lake models @@ -10792,6 +10571,7 @@ Acceptable values are: `CROCUS81 initial SNOWMAK_dz:` specifies the initial depth from snow making process. + .Example _lis.config_ entry .... CROCUS81 model timestep: 15mn @@ -11073,6 +10853,7 @@ sample MODEL_OUTPUT_LIST.TBL file for the complete specification. Model output attributes file: './MODEL_OUTPUT_LIST.TBL' .... + [[ssec_timeinterval,Defining a time interval]] === Defining a time interval From f545dc3679f841cfc93de9d925c20bc9671be2ee Mon Sep 17 00:00:00 2001 From: Eric Kemp Date: Thu, 1 Feb 2024 10:13:46 -0500 Subject: [PATCH 4/8] Tweaks to satisfy GNU and Intel compilers with strict checks. --- lis/metforcing/mogreps_g/get_cdf_params.F90 | 1 - lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 | 1 + lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lis/metforcing/mogreps_g/get_cdf_params.F90 b/lis/metforcing/mogreps_g/get_cdf_params.F90 index 7baec6b5f..b63fb041e 100644 --- a/lis/metforcing/mogreps_g/get_cdf_params.F90 +++ b/lis/metforcing/mogreps_g/get_cdf_params.F90 @@ -22,7 +22,6 @@ subroutine get_cdf_params (n, fname, month, param_a, param_b, mean, std) !USES: use LIS_coreMod use LIS_logMod - use mogrepsg_forcingMod, only : mogrepsg_struc #if (defined USE_NETCDF3 || defined USE_NETCDF4) use netcdf #endif diff --git a/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 b/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 index e90cb40b5..98dc9d04a 100644 --- a/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 +++ b/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 @@ -137,6 +137,7 @@ subroutine init_mogrepsg(findex) external :: bilinear_interp_input external :: conserv_interp_input external :: neighbor_interp_input + external :: get_cdf_params write(LIS_logunit,*) "[INFO] Initializing the MOGREPS-G forecast inputs " diff --git a/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 b/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 index efb0b4d8f..ea6537c25 100644 --- a/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 +++ b/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 @@ -244,7 +244,7 @@ subroutine timeinterp_mogrepsg(n,findex) if (mogrepsg_struc(n)%bc == 1) then !1 - use; or 0 if(mogrepsg_struc(n)%pcp_bc(m,index1).ne.LIS_rc%udef) then ! account for the accum fields - pcp(tid)=mogrepsg_struc(n)%pcp_bc(m,index1)/(3600*3) + pcp(tid)=mogrepsg_struc(n)%pcp_bc(m,index1)/real(3600*3) if(pcp(tid).lt.0) then pcp(tid) = 0.0 endif @@ -252,7 +252,7 @@ subroutine timeinterp_mogrepsg(n,findex) else !don't apply bias correction if(mogrepsg_struc(n)%metdata2(8,m,index1).ne.LIS_rc%udef) then ! account for the accum fields - pcp(tid)=(mogrepsg_struc(n)%metdata2(8,m,index1)-mogrepsg_struc(n)%metdata1(8,m,index1))/(3600*3) + pcp(tid)=(mogrepsg_struc(n)%metdata2(8,m,index1)-mogrepsg_struc(n)%metdata1(8,m,index1))/real(3600*3) if(pcp(tid).lt.0) then pcp(tid) = 0.0 endif From 663ae0b16b3a15e237bd19cdda750f4e96d1c055 Mon Sep 17 00:00:00 2001 From: Eric Kemp Date: Thu, 1 Feb 2024 10:51:16 -0500 Subject: [PATCH 5/8] Restored earlier lis.config entries unrelated to MOGREPS-G. --- lis/configs/lis.config.adoc | 224 +++++++++++++++++++++++++++++++++++- 1 file changed, 222 insertions(+), 2 deletions(-) diff --git a/lis/configs/lis.config.adoc b/lis/configs/lis.config.adoc index 3f9ed1881..47a5991ea 100644 --- a/lis/configs/lis.config.adoc +++ b/lis/configs/lis.config.adoc @@ -188,6 +188,33 @@ endif::devonly[] Land surface model: Noah.2.7.1 .... +`Number of subLSMs:` specifies the number of sub-level LSMs +or specialized models that may interface with other LSMs in LIS. +Entry here can be set to 1 with having a surface model type +specified, such as "LSM", and set to 1. + +.Example _lis.config_ entry +.... +Number of subLSMs: 1 +.... + +`subLSM models:` specifies the sub-level land surface model to run. +Acceptable values are: + +|==== +|Value | Description + +|none | template lsm +|Crocus8.1 | Crocus version 8.1 snow model +|SnowModel | Glen Liston's SnowModel snow model +|==== + +.Example _lis.config_ entry +.... +subLSM models: "Crocus8.1" +.... + + `Lake model:` specifies the lake model to run. Acceptable values are: @@ -324,6 +351,7 @@ Acceptable values for the sources are: |"`GLDAS`" | GLDAS |"`GFS`" | GFS |"`MERRA2`" | MERRA2 +|"`GEOS-IT`" | GEOS-IT |"`CMAP`" | CMAP |"`TRMM 3B42RT`" | TRMM 3B42RT |"`TRMM 3B42RTV7`" | TRMM 3B42RTV7 @@ -386,6 +414,8 @@ Acceptable values are: |"`none`" | Do not apply topographic correction for forcing |"`lapse-rate`" | Use lapse rate correction for forcing |"`slope-aspect`" | Apply slope-aspect correction for forcing +|"`lapse-rate and slope-aspect`" | Apply both lapse-rate and slope-aspect corrections +|"`micromet`" | Apply Glen Liston's MicroMet corrections to forcing fields |==== .Example _lis.config_ entry @@ -636,6 +666,18 @@ AGRMET area of data: GLOBAL .... ==== +`Number of dimensions in the lat/lon output fields:` specifies the number of dimensions to use when writing the latitude and longitude fields of the LIS output. This is an optional entry. If this entry is not used, LIS will attempt to write the lat/lon fields in 1D. If the projection being used is not compatible with 1D, LIS will write in 2D. +Acceptable values are: +|==== +|Value | Description +|"1D" | 1 dimensional latitude and longitude output + (Note: Only the latlon projection supports 1D output) +|"2D" | 2 dimensional latitude and longitude output +|==== +.Example _lis.config_ entry +.... +Number of dimensions in the lat/lon output fields: "1D" +.... `Enable output statistics:` specifies whether to write the ASCII statistics file for the output data. @@ -3021,9 +3063,11 @@ and observation standard deviation. `SMAP(NASA) model CDF file:` specifies the name of the model CDF file (observations will be scaled into this climatology). +Note: Soil moisture CDF grouped (stratified) by land cover or precipitation climatology or both simultaneously also can be used here. `SMAP(NASA) observation CDF file:` specifies the name of the observation CDF file. +Note: Soil moisture CDF grouped (stratified) by land cover or precipitation climatology or both simultaneously also can be used here. `SMAP(NASA) soil moisture number of bins in the CDF:` specifies the number of bins in the CDF. @@ -3054,6 +3098,32 @@ SMAP(NASA) soil moisture number of bins in the CDF: SMAP(NASA) CDF read option: .... +[[sssec_cdftransfersmda,Transfering stratified CDFs from one domain to another]] +==== Transfering stratified CDFs from one domain to another + +`Use CDF transfer for soil moisture data assimilation:` specifies +whether to use CDF transfer method. + +`Reference domain model CDF file:` specifies the reference domain model CDF name and data directory. + +`Reference domain obs CDF file:` specifies the reference domain obs CDF name and data directory. + +`Number of bins in the soil moisture CDF:` specifies the number of bins in the CDF. + +`Reference domain precipitation climatology data source:` specifies the reference domain precipitation climatology generated by LVT. + +`Target domain precipitation climatology data source:` specifies the target domain precipitation climatology generated by LVT. + + +.Example _lis.config_ entry +.... +Use CDF transfer for soil moisture data assimilation: +Reference domain model CDF file: ref_model_cdf_forcing_diff/stratified_cdf_noahmp401.nc +Reference domain obs CDF file: ref_obs_cdf_forcing_diff/stratified_cdf_smapobs.nc +Number of bins in the soil moisture CDF: 100 +Reference domain precipitation climatology data source: Precip.climo.us.nldas2/LVT_MEAN_FINAL.202201010000.d01.nc +Target domain precipitation climatology data source: Precip.climo.eu.merra/LVT_MEAN_FINAL.202201010000.d01.nc +.... [[sssec_smapnrtsmda,SMAP (NRT) soil moisture assimilation]] ==== SMAP (NRT) soil moisture assimilation @@ -5634,6 +5704,50 @@ MERRA2 use 2m wind fields: 0 MERRA2 use corrected total precipitation: 1 .... +[[sssec_forcings_GEOS-IT,GEOS-IT]] +==== GEOS-IT + +`GEOS-IT forcing directory:` specifies the location of +the GEOS-IT forcing files. + +Please note that GEOS-IT is currently in production and is +not complete for all calendar years. Also, it is not yet +available outside of NASA`'s NCCS computing platforms. +Also, the topographic or elevation correction option is +supported through the MERRA-2 geopotential terrain height +file. Please also see the latest LDT notes for updates on +how to use this option. + +`GEOS-IT use lowest model level forcing:` specifies whether +to use the lowest model level forcing. +Acceptable values are: + +|==== +|Value | Description + +|0 | Do not use the lowest model level forcing. +|1 | Use the lowest model level forcing. +|==== + +`GEOS-IT use 2m wind fields:` specifies whether to use the +2m diagnosed wind fields. This option will only work if +the lowest model level forcing option is turned off. +Acceptable values are: + +|==== +|Value | Description + +|0 | Do not use the 2m diagnosed wind speed fields. +|1 | Use the 2m diagnosed wind speed fields. +|==== + +.Example _lis.config_ entry +.... +GEOS-IT forcing directory: ./GEOS-IT +GEOS-IT use lowest model level forcing: 1 +GEOS-IT use 2m wind fields: 0 +.... + [[sssec_forcings_ERA5,ERA5]] ==== ERA5 @@ -5888,8 +6002,18 @@ default to the "`final`" product of GPM IMERG. `IMERG version:` specifies the version of the GPM IMERG precipitation forcing files. If no version is specified, -the reader will default to the latest version of GPM IMERG. -(Currently V06B). +the reader will default to "`V06B`". + +The supported versions of GPM IMERG are: + +|==== +|Version | Product + +|V06B | early, late, final +|V06C | early, late, final +|V06D | early, late, final +|V07A | preliminary support for final +|==== .Example _lis.config_ entry .... @@ -9549,6 +9673,102 @@ AWRAL600 initial sd: 0.5 0.5 AWRAL600 initial mleaf: 0.67 0.2 .... +[[ssec_sublsm,Sublevel land surface models]] +=== Sublevel land surface models + + +[[sssec_sublsm_snowmodel,SnowModel]] +==== SnowModel, Liston + +`SnowModel model timestep:` specifies the timestep for the run. + +See Section <> for a description +of how to specify a time interval. + +`SnowModel restart output interval:` defines the restart +writing interval for Glen Liston's SnowModel model. The typical +value used in the LIS runs is 24 hours (1da). + +See Section <> for a description +of how to specify a time interval. + +`SnowModel restart file:` specifies the SnowModel active +restart file. + +`SnowModel restart file format:` specifies the restart file +format for SnowModel. + +`SnowModel parameter file:` specifies the main SnowModel-specific +input and option parameter configuration file, which is needed +to run SnowModel. + +`SnowModel parameters source option:` specifies if SnowModel will +read in its native binary parameter files from within the SnowModel +code or what is preprocessed in LDT. LDT option supports parallel runs +Acceptable values are: + +|==== +|Value | Description + +|SnowModel | Use SnowModel built-in routines to read in +|LDT | Use the LIS SnowModel main driver to load parameters from LDT. +|==== + +`SnowModel MicroMet input source:` specifies if SnowModel will +read in its own specifically formatted binary or ASCII table forcing +files, or if LIS meteorological forcing fields will be passed in, +with the option to turn on MicroMet topographic-downscaling options +on the LIS metforcing layer side. To turn on "micromet" option in LIS, +set Topographic correction method (met forcing) to micromet. +Acceptable values are: + +|==== +|Value | Description + +|SnowModel | Readin specific SnowModel forcing files +|LIS | LIS-based meteorological forcing fields +|==== + +`SnowModel preprocess code option:` specifies the turning on +of the SnowModel built-in preprocess code module, which performs +initial preprocessing of gridded data for running the model. +Currently, only option supported is 1 (on). + +`Write out SnowModel forcing file fields:` specifies if you +want to write out SnowModel forcing fields generated by reading +in SnowModel-specific forcing files. This option is mainly +used when SnowModel MicroMet input source is set to SnowModel +and you run SnowModel in offline subLSM mode (no other LSMs or models +run with this submodel). Selecting 1 activates this option, and +0 indicates off. + +`SnowModel number of snow layers:` specifies the number of snow +layers that would be allowed to build within the SnowModel runtime. +This option is currently set to 1 within LIS, and must also be +activated and increased by setting the multiple layer snow model +scheme in the SnowModel option parameter file (snowmodel.par). + +`SnowModel initial snow water equivalent:` specifies the initial +snow water equivalent (SWE) value. This is currently set to +default values found in the coldstart mode for model restart reads, +based on a SnowModel initialization approach. + +.Example _lis.config_ entry +.... +SnowModel model timestep: 1hr +SnowModel restart file: ./none +SnowModel restart output interval: 1mo +SnowModel restart file format: "netcdf" +SnowModel parameter file: ./snowmodel.par +SnowModel parameters source option: LDT +SnowModel MicroMet input source: LIS +Write out SnowModel forcing file fields: 1 +SnowModel preprocess code option: 1 +SnowModel number of snow layers: 1 +SnowModel initial snow water equivalent: 0.0 +.... + + [[ssec_lakes,Lake models]] === Lake models From 47c1e6183d7b20f6eee31abeb92ad02fbfdd27d6 Mon Sep 17 00:00:00 2001 From: Eric Kemp Date: Thu, 1 Feb 2024 10:54:05 -0500 Subject: [PATCH 6/8] Fixed cut-and-paste. --- lis/configs/lis.config.adoc | 52 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/lis/configs/lis.config.adoc b/lis/configs/lis.config.adoc index 47a5991ea..9f5fdac6f 100644 --- a/lis/configs/lis.config.adoc +++ b/lis/configs/lis.config.adoc @@ -3098,32 +3098,6 @@ SMAP(NASA) soil moisture number of bins in the CDF: SMAP(NASA) CDF read option: .... -[[sssec_cdftransfersmda,Transfering stratified CDFs from one domain to another]] -==== Transfering stratified CDFs from one domain to another - -`Use CDF transfer for soil moisture data assimilation:` specifies -whether to use CDF transfer method. - -`Reference domain model CDF file:` specifies the reference domain model CDF name and data directory. - -`Reference domain obs CDF file:` specifies the reference domain obs CDF name and data directory. - -`Number of bins in the soil moisture CDF:` specifies the number of bins in the CDF. - -`Reference domain precipitation climatology data source:` specifies the reference domain precipitation climatology generated by LVT. - -`Target domain precipitation climatology data source:` specifies the target domain precipitation climatology generated by LVT. - - -.Example _lis.config_ entry -.... -Use CDF transfer for soil moisture data assimilation: -Reference domain model CDF file: ref_model_cdf_forcing_diff/stratified_cdf_noahmp401.nc -Reference domain obs CDF file: ref_obs_cdf_forcing_diff/stratified_cdf_smapobs.nc -Number of bins in the soil moisture CDF: 100 -Reference domain precipitation climatology data source: Precip.climo.us.nldas2/LVT_MEAN_FINAL.202201010000.d01.nc -Target domain precipitation climatology data source: Precip.climo.eu.merra/LVT_MEAN_FINAL.202201010000.d01.nc -.... [[sssec_smapnrtsmda,SMAP (NRT) soil moisture assimilation]] ==== SMAP (NRT) soil moisture assimilation @@ -3168,6 +3142,32 @@ SMAP(NRT) soil moisture number of bins in the CDF: SMAP(NRT) CDF read option: .... +[[sssec_cdftransfersmda,Transfering stratified CDFs from one domain to another]] +==== Transfering stratified CDFs from one domain to another + +`Use CDF transfer for soil moisture data assimilation:` specifies +whether to use CDF transfer method. + +`Reference domain model CDF file:` specifies the reference domain model CDF name and data directory. + +`Reference domain obs CDF file:` specifies the reference domain obs CDF name and data directory. + +`Number of bins in the soil moisture CDF:` specifies the number of bins in the CDF. + +`Reference domain precipitation climatology data source:` specifies the reference domain precipitation climatology generated by LVT. + +`Target domain precipitation climatology data source:` specifies the target domain precipitation climatology generated by LVT. + + +.Example _lis.config_ entry +.... +Use CDF transfer for soil moisture data assimilation: +Reference domain model CDF file: ref_model_cdf_forcing_diff/stratified_cdf_noahmp401.nc +Reference domain obs CDF file: ref_obs_cdf_forcing_diff/stratified_cdf_smapobs.nc +Number of bins in the soil moisture CDF: 100 +Reference domain precipitation climatology data source: Precip.climo.us.nldas2/LVT_MEAN_FINAL.202201010000.d01.nc +Target domain precipitation climatology data source: Precip.climo.eu.merra/LVT_MEAN_FINAL.202201010000.d01.nc +.... [[sssec_smapnasavodda,SMAP (NASA) vegetation optical depth assimilation]] ==== SMAP (NASA) vegetation optical depth assimilation From bb1a6f33acdb0d2850584efafa389bdadb5ccdc7 Mon Sep 17 00:00:00 2001 From: Eric Kemp Date: Thu, 1 Feb 2024 10:57:22 -0500 Subject: [PATCH 7/8] Further tweaks to ldt.config.adoc. --- lis/configs/lis.config.adoc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lis/configs/lis.config.adoc b/lis/configs/lis.config.adoc index 9f5fdac6f..39cb41f6c 100644 --- a/lis/configs/lis.config.adoc +++ b/lis/configs/lis.config.adoc @@ -215,7 +215,6 @@ subLSM models: "Crocus8.1" .... - `Lake model:` specifies the lake model to run. Acceptable values are: @@ -5648,7 +5647,6 @@ GFS domain y-dimension size: 256 GFS number of forcing variables: 10 .... - [[sssec_forcings_MERRA2,MERRA2]] ==== MERRA2 @@ -10791,7 +10789,6 @@ Acceptable values are: `CROCUS81 initial SNOWMAK_dz:` specifies the initial depth from snow making process. - .Example _lis.config_ entry .... CROCUS81 model timestep: 15mn @@ -11073,7 +11070,6 @@ sample MODEL_OUTPUT_LIST.TBL file for the complete specification. Model output attributes file: './MODEL_OUTPUT_LIST.TBL' .... - [[ssec_timeinterval,Defining a time interval]] === Defining a time interval From 82f8083c5e9561254a951c20bb9f65fef639a429 Mon Sep 17 00:00:00 2001 From: Eric Kemp Date: Thu, 1 Feb 2024 15:05:19 -0500 Subject: [PATCH 8/8] Some style updates to make the code easier to read. Identical results are given to older GNU and Intel compiler runs. --- lis/metforcing/mogreps_g/get_cdf_params.F90 | 144 ++++---- lis/metforcing/mogreps_g/get_mogrepsg.F90 | 202 +++++++----- .../mogreps_g/mogrepsg_forcingMod.F90 | 58 ++-- lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 | 75 +++-- .../mogreps_g/timeinterp_mogrepsg.F90 | 308 ++++++++++-------- 5 files changed, 438 insertions(+), 349 deletions(-) diff --git a/lis/metforcing/mogreps_g/get_cdf_params.F90 b/lis/metforcing/mogreps_g/get_cdf_params.F90 index b63fb041e..5d9c0fc07 100644 --- a/lis/metforcing/mogreps_g/get_cdf_params.F90 +++ b/lis/metforcing/mogreps_g/get_cdf_params.F90 @@ -28,82 +28,85 @@ subroutine get_cdf_params (n, fname, month, param_a, param_b, mean, std) implicit none - !ARGUMENTS: + !ARGUMENTS: integer, intent(in) :: n character(len=*), intent(in) :: fname integer, intent(in) :: month ! month of year (1-12) - !EOP - logical :: file_exists - integer :: ftn - integer :: param_a_id, param_b_id, mean_id, std_id, ngrid_id, nlead_id - integer :: ngrid, nlead - integer :: r, c, nc, c1, r1, gid, l - real,allocatable :: param_hires(:,:) - real,allocatable :: param_hires_2d(:,:) - real :: param_a(LIS_rc%ngrid(n),8) !8: lead time - real :: param_b(LIS_rc%ngrid(n),8) - real :: mean(LIS_rc%ngrid(n),8) - real :: std(LIS_rc%ngrid(n),8) - - ! check file + !EOP + logical :: file_exists + integer :: ftn + integer :: param_a_id, param_b_id, mean_id, & + std_id, ngrid_id, nlead_id + integer :: ngrid, nlead + integer :: r, c, nc, c1, r1, gid, l + real, allocatable :: param_hires(:,:) + real, allocatable :: param_hires_2d(:,:) + real :: param_a(LIS_rc%ngrid(n),8) !8:lead time + real :: param_b(LIS_rc%ngrid(n),8) + real :: mean(LIS_rc%ngrid(n),8) + real :: std(LIS_rc%ngrid(n),8) + + ! check file inquire(file=fname, exist=file_exists) - if(.not. file_exists) then - write(LIS_logunit,*) '[ERR] ',trim(fname)//' does not exist' + if (.not. file_exists) then + write(LIS_logunit,*) '[ERR] ', trim(fname) // ' does not exist' call LIS_endrun() endif - write(LIS_logunit,*)'[INFO] Getting MOGREPS-G bias correction parameters ', trim(fname) + write(LIS_logunit,*) & + '[INFO] Getting MOGREPS-G bias correction parameters ', trim(fname) call LIS_verify(nf90_open(path=trim(fname), mode=NF90_NOWRITE, & ncid=ftn), 'nf90_open failed in get_cdf_params') call LIS_verify(nf90_inq_dimid(ftn, "ngrid", ngrid_id), & - 'nf90_inq_dimid failed for ngrid in get_cdf_params') + 'nf90_inq_dimid failed for ngrid in get_cdf_params') call LIS_verify(nf90_inquire_dimension(ftn, ngrid_id, len=ngrid),& - 'nf90_inquire_dimension failed for ngrid in get_cdf_params') + 'nf90_inquire_dimension failed for ngrid in get_cdf_params') - if(LIS_rc%gnc(n)*LIS_rc%gnr(n) .ne. ngrid) then - write(LIS_logunit,*) 'The input dimensions of the '//trim(fname) + if (LIS_rc%gnc(n)*LIS_rc%gnr(n) .ne. ngrid) then + write(LIS_logunit,*) '[ERR] The input dimensions of the '//trim(fname) write(LIS_logunit,*) '(',ngrid,')' - write(LIS_logunit,*) 'does not match the dimensions in the LIS parameter file' + write(LIS_logunit,*) & + 'does not match the dimensions in the LIS parameter file' write(LIS_logunit,*) '(',LIS_rc%gnc(n)*LIS_rc%gnr(n),')' call LIS_endrun() endif call LIS_verify(nf90_inq_dimid(ftn, "lead_time", nlead_id), & - 'nf90_inq_dimid failed for nlead in get_cdf_params') + 'nf90_inq_dimid failed for nlead in get_cdf_params') call LIS_verify(nf90_inquire_dimension(ftn, nlead_id, len=nlead),& - 'nf90_inquire_dimension failed for nlead in get_cdf_params') + 'nf90_inquire_dimension failed for nlead in get_cdf_params') - allocate(param_hires(LIS_rc%gnc(n)*LIS_rc%gnr(n),nlead)) + allocate(param_hires(LIS_rc%gnc(n)*LIS_rc%gnr(n),nlead)) allocate(param_hires_2d(LIS_rc%gnc(n),LIS_rc%gnr(n))) param_hires = -9999.0 param_hires_2d = -9999.0 - + ! read param_a - call LIS_verify(nf90_inq_varid(ftn,'cdf_param_a',param_a_id), & + call LIS_verify(nf90_inq_varid(ftn, 'cdf_param_a', param_a_id), & 'nf90_inq_varid failed for cdf_param_a in get_cdf_params') call LIS_verify(nf90_get_var(ftn, param_a_id, param_hires, & - start=(/1,1,month/), count=(/ngrid,nlead,1/)),& + start=(/1,1,month/), count=(/ngrid,nlead,1/)), & 'nf90_get_var failed for cdf_param_a in get_cdf_params') - - do l=1,nlead + + do l = 1, nlead ! 1D -> 2D - do r=1,LIS_rc%gnr(n) - do c=1,LIS_rc%gnc(n) - param_hires_2d(c,r)=param_hires(c+(r-1)*LIS_rc%gnc(n),l) + do r = 1, LIS_rc%gnr(n) + do c = 1, LIS_rc%gnc(n) + param_hires_2d(c,r) = param_hires(c+(r-1)*LIS_rc%gnc(n),l) enddo enddo !subsets the data for each processor's domain nc = (LIS_ewe_halo_ind(n,LIS_localPet+1)-LIS_ews_halo_ind(n,LIS_localPet+1))+1 - do r=LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) - do c=LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) - c1 = c-LIS_ews_halo_ind(n,LIS_localPet+1)+1 - r1 = r-LIS_nss_halo_ind(n,LIS_localPet+1)+1 + do r = LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) + do c = LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) + c1 = c - LIS_ews_halo_ind(n,LIS_localPet+1)+1 + r1 = r - LIS_nss_halo_ind(n,LIS_localPet+1)+1 gid = LIS_domain(n)%gindex(c1,r1) - if(gid.ne.-1) then + if (gid .ne. -1) then param_a(gid,l) = param_hires_2d(c,r) endif enddo @@ -111,28 +114,28 @@ subroutine get_cdf_params (n, fname, month, param_a, param_b, mean, std) enddo ! read param_b - call LIS_verify(nf90_inq_varid(ftn,'cdf_param_b',param_b_id), & + call LIS_verify(nf90_inq_varid(ftn, 'cdf_param_b', param_b_id), & 'nf90_inq_varid failed for cdf_param_b in get_cdf_params') call LIS_verify(nf90_get_var(ftn, param_b_id, param_hires, & start=(/1,1,month/), count=(/ngrid,nlead,1/)),& 'nf90_get_var failed for cdf_param_b in get_cdf_params') - do l=1,nlead + do l = 1, nlead ! 1D -> 2D - do r=1,LIS_rc%gnr(n) - do c=1,LIS_rc%gnc(n) - param_hires_2d(c,r)=param_hires(c+(r-1)*LIS_rc%gnc(n),l) + do r = 1, LIS_rc%gnr(n) + do c = 1,LIS_rc%gnc(n) + param_hires_2d(c,r) = param_hires(c+(r-1)*LIS_rc%gnc(n),l) enddo enddo !subsets the data for each processor's domain nc = (LIS_ewe_halo_ind(n,LIS_localPet+1)-LIS_ews_halo_ind(n,LIS_localPet+1))+1 - do r=LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) - do c=LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) - c1 = c-LIS_ews_halo_ind(n,LIS_localPet+1)+1 - r1 = r-LIS_nss_halo_ind(n,LIS_localPet+1)+1 + do r = LIS_nss_halo_ind(n,LIS_localPet+1), LIS_nse_halo_ind(n,LIS_localPet+1) + do c = LIS_ews_halo_ind(n,LIS_localPet+1), LIS_ewe_halo_ind(n,LIS_localPet+1) + c1 = c - LIS_ews_halo_ind(n,LIS_localPet+1) + 1 + r1 = r - LIS_nss_halo_ind(n,LIS_localPet+1) + 1 gid = LIS_domain(n)%gindex(c1,r1) - if(gid.ne.-1) then + if (gid.ne.-1) then param_b(gid,l) = param_hires_2d(c,r) endif enddo @@ -140,28 +143,28 @@ subroutine get_cdf_params (n, fname, month, param_a, param_b, mean, std) enddo ! read mean - call LIS_verify(nf90_inq_varid(ftn,'mean',mean_id), & + call LIS_verify(nf90_inq_varid(ftn, 'mean', mean_id), & 'nf90_inq_varid failed for mean in get_cdf_params') call LIS_verify(nf90_get_var(ftn, mean_id, param_hires, & start=(/1,1,month/), count=(/ngrid,nlead,1/)),& 'nf90_get_var failed for mean in get_cdf_params') - do l=1,nlead + do l = 1, nlead ! 1D -> 2D - do r=1,LIS_rc%gnr(n) - do c=1,LIS_rc%gnc(n) - param_hires_2d(c,r)=param_hires(c+(r-1)*LIS_rc%gnc(n),l) + do r = 1, LIS_rc%gnr(n) + do c = 1, LIS_rc%gnc(n) + param_hires_2d(c,r) = param_hires(c+(r-1)*LIS_rc%gnc(n),l) enddo enddo !subsets the data for each processor's domain nc = (LIS_ewe_halo_ind(n,LIS_localPet+1)-LIS_ews_halo_ind(n,LIS_localPet+1))+1 - do r=LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) - do c=LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) - c1 = c-LIS_ews_halo_ind(n,LIS_localPet+1)+1 - r1 = r-LIS_nss_halo_ind(n,LIS_localPet+1)+1 + do r = LIS_nss_halo_ind(n,LIS_localPet+1), LIS_nse_halo_ind(n,LIS_localPet+1) + do c = LIS_ews_halo_ind(n,LIS_localPet+1), LIS_ewe_halo_ind(n,LIS_localPet+1) + c1 = c - LIS_ews_halo_ind(n,LIS_localPet+1)+1 + r1 = r - LIS_nss_halo_ind(n,LIS_localPet+1)+1 gid = LIS_domain(n)%gindex(c1,r1) - if(gid.ne.-1) then + if (gid.ne.-1) then mean(gid,l) = param_hires_2d(c,r) endif enddo @@ -169,28 +172,28 @@ subroutine get_cdf_params (n, fname, month, param_a, param_b, mean, std) enddo ! read std - call LIS_verify(nf90_inq_varid(ftn,'std',std_id), & + call LIS_verify(nf90_inq_varid(ftn, 'std', std_id), & 'nf90_inq_varid failed for std in get_cdf_params') call LIS_verify(nf90_get_var(ftn, std_id, param_hires, & start=(/1,1,month/), count=(/ngrid,nlead,1/)),& 'nf90_get_var failed for std in get_cdf_params') - do l=1,nlead + do l = 1, nlead ! 1D -> 2D - do r=1,LIS_rc%gnr(n) - do c=1,LIS_rc%gnc(n) - param_hires_2d(c,r)=param_hires(c+(r-1)*LIS_rc%gnc(n),l) + do r = 1, LIS_rc%gnr(n) + do c = 1, LIS_rc%gnc(n) + param_hires_2d(c,r) =param_hires(c+(r-1)*LIS_rc%gnc(n),l) enddo enddo !subsets the data for each processor's domain nc = (LIS_ewe_halo_ind(n,LIS_localPet+1)-LIS_ews_halo_ind(n,LIS_localPet+1))+1 - do r=LIS_nss_halo_ind(n,LIS_localPet+1),LIS_nse_halo_ind(n,LIS_localPet+1) - do c=LIS_ews_halo_ind(n,LIS_localPet+1),LIS_ewe_halo_ind(n,LIS_localPet+1) - c1 = c-LIS_ews_halo_ind(n,LIS_localPet+1)+1 - r1 = r-LIS_nss_halo_ind(n,LIS_localPet+1)+1 + do r = LIS_nss_halo_ind(n,LIS_localPet+1), LIS_nse_halo_ind(n,LIS_localPet+1) + do c = LIS_ews_halo_ind(n,LIS_localPet+1), LIS_ewe_halo_ind(n,LIS_localPet+1) + c1 = c - LIS_ews_halo_ind(n,LIS_localPet+1) + 1 + r1 = r - LIS_nss_halo_ind(n,LIS_localPet+1) + 1 gid = LIS_domain(n)%gindex(c1,r1) - if(gid.ne.-1) then + if (gid.ne.-1) then std(gid,l) = param_hires_2d(c,r) endif enddo @@ -202,7 +205,8 @@ subroutine get_cdf_params (n, fname, month, param_a, param_b, mean, std) call LIS_verify(nf90_close(ftn),'failed to close in get_cdf_params') - write(LIS_logunit,*) 'Done reading MOGREPS-G bias correction parameters data ' + write(LIS_logunit,*) & + '[INFO] Done reading MOGREPS-G bias correction parameters data ' end subroutine get_cdf_params diff --git a/lis/metforcing/mogreps_g/get_mogrepsg.F90 b/lis/metforcing/mogreps_g/get_mogrepsg.F90 index 9877b0599..610802273 100644 --- a/lis/metforcing/mogreps_g/get_mogrepsg.F90 +++ b/lis/metforcing/mogreps_g/get_mogrepsg.F90 @@ -64,134 +64,156 @@ subroutine get_mogrepsg(n, findex) external :: read_mogrepsg ! MOGREPS-G cycles every 6 hours; ecch cycle provide up to 192 hours (8 days; 3-hour interval) forecast - if(LIS_rc%ts.gt.10800) then - write(LIS_logunit,*) '[WARN] The model timestep is > forcing data timestep ...' - write(LIS_logunit,*) '[WARN] LIS does not support this mode currently.' + if (LIS_rc%ts .gt. 10800) then + write(LIS_logunit,*) '[ERR] The model timestep is > forcing data timestep ...' + write(LIS_logunit,*) '[ERR] LIS does not support this mode currently.' call LIS_endrun() endif - openfile=0 + openfile = 0 - if(LIS_rc%tscount(n).eq.1 .or.LIS_rc%rstflag(n).eq.1) then !beginning of run + if (LIS_rc%tscount(n) .eq. 1 .or. LIS_rc%rstflag(n) .eq. 1) then !beginning of run LIS_rc%rstflag(n) = 0 endif ! First timestep of run - if(LIS_rc%tscount(n).eq.1 .or.LIS_rc%rstflag(n).eq.1) then - ! Bookend-time record 1 + if (LIS_rc%tscount(n) .eq. 1 .or. LIS_rc%rstflag(n) .eq. 1) then + ! Bookend-time record 1 yr1 = LIS_rc%yr - mo1=LIS_rc%mo - da1=LIS_rc%da - hr1=LIS_rc%hr - mn1=0 - ss1=0 - ts1=0 - call LIS_tick(time1,doy1,gmt1,yr1,mo1,da1,hr1,mn1,ss1,ts1) + mo1 = LIS_rc%mo + da1 = LIS_rc%da + hr1 = LIS_rc%hr + mn1 = 0 + ss1 = 0 + ts1 = 0 + call LIS_tick(time1, doy1, gmt1, yr1, mo1, da1, hr1, mn1, ss1, ts1) ! Bookend-time record 2 - yr2=LIS_rc%yr !next hour - mo2=LIS_rc%mo - da2=LIS_rc%da - hr2=3 - mn2=0 - ss2=0 - ts2=0 - call LIS_tick(time2,doy2,gmt2,yr2,mo2,da2,hr2,mn2,ss2,ts2) + yr2 = LIS_rc%yr !next hour + mo2 = LIS_rc%mo + da2 = LIS_rc%da + hr2 = 3 + mn2 = 0 + ss2 = 0 + ts2 = 0 + call LIS_tick(time2, doy2, gmt2, yr2, mo2, da2, hr2, mn2, ss2, ts2) openfile=1 endif - ! 3 hourly interval + ! 3 hourly interval fcsthr_intv = 3 valid_hour = fcsthr_intv * (LIS_rc%hr/fcsthr_intv) - if((valid_hour==LIS_rc%hr .and. LIS_rc%mn==0) .or. & + if ((valid_hour == LIS_rc%hr .and. LIS_rc%mn == 0) .or. & openfile == 1) then ! Forecast hour condition within each file: - mogrepsg_struc(n)%fcst_hour = mogrepsg_struc(n)%fcst_hour + fcsthr_intv - + mogrepsg_struc(n)%fcst_hour = & + mogrepsg_struc(n)%fcst_hour + fcsthr_intv + ! Check if local forecast hour exceeds max grib file forecast hour: - if(mogrepsg_struc(n)%fcst_hour > 195 ) then + if (mogrepsg_struc(n)%fcst_hour > 195 ) then write(LIS_logunit,*) & - "[INFO] MOGREPS-G Forecast hour has exceeded the grib file's final" + "[ERR] MOGREPS-G Forecast hour has exceeded the grib file's final" write(LIS_logunit,*) & ' forecast hour (record). Run will end here for now ... ' call LIS_endrun endif - + ! Update bookend-time record 2: - if(LIS_rc%tscount(n).ne.1) then - mogrepsg_struc(n)%fcsttime1=mogrepsg_struc(n)%fcsttime2 - mogrepsg_struc(n)%metdata1(:,:,:)=mogrepsg_struc(n)%metdata2(:,:,:) - - yr2=LIS_rc%yr - mo2=LIS_rc%mo - da2=LIS_rc%da - hr2=valid_hour - mn2=fcsthr_intv*60 ! Backward looking - ss2=0 - ts2=0 - call LIS_tick(time2,doy2,gmt2,yr2,mo2,da2,hr2,mn2,ss2,ts2) + if (LIS_rc%tscount(n) .ne. 1) then + mogrepsg_struc(n)%fcsttime1 = mogrepsg_struc(n)%fcsttime2 + mogrepsg_struc(n)%metdata1(:,:,:) = & + mogrepsg_struc(n)%metdata2(:,:,:) + + yr2 = LIS_rc%yr + mo2 = LIS_rc%mo + da2 = LIS_rc%da + hr2 = valid_hour + mn2 = fcsthr_intv * 60 ! Backward looking + ss2 = 0 + ts2 = 0 + call LIS_tick(time2, doy2, gmt2, yr2, mo2, da2, hr2, mn2, ss2, & + ts2) endif - do m=1,mogrepsg_struc(n)%max_ens_members + do m = 1, mogrepsg_struc(n)%max_ens_members ! Read in file contents: - if(LIS_rc%tscount(n) == 1) then ! Read in first two book-ends - ferror=0 - order=1 - call get_mogrepsg_filename(mogrepsg_struc(n)%odir,mogrepsg_struc(n)%init_yr,& - mogrepsg_struc(n)%init_mo,mogrepsg_struc(n)%init_da,mogrepsg_struc(n)%init_hr,& - 0,m,fname) - - write(LIS_logunit,*)'[INFO] Getting MOGREPS-G forecast file1 ... ',trim(fname) + if (LIS_rc%tscount(n) == 1) then ! Read in first two book-ends + ferror = 0 + order = 1 + call get_mogrepsg_filename(mogrepsg_struc(n)%odir, & + mogrepsg_struc(n)%init_yr, & + mogrepsg_struc(n)%init_mo, & + mogrepsg_struc(n)%init_da, & + mogrepsg_struc(n)%init_hr, & + 0, m, fname) + + write(LIS_logunit,*)& + '[INFO] Getting MOGREPS-G forecast file1 ... ', & + trim(fname) call read_mogrepsg(n, m, findex, order, fname, ferror) - if(ferror.ge.1) mogrepsg_struc(n)%fcsttime1=time1 - - ferror=0 - order=2 - call get_mogrepsg_filename(mogrepsg_struc(n)%odir,mogrepsg_struc(n)%init_yr,& - mogrepsg_struc(n)%init_mo,mogrepsg_struc(n)%init_da,mogrepsg_struc(n)%init_hr,& - mogrepsg_struc(n)%fcst_hour,m,fname) - - write(LIS_logunit,*)'[INFO] Getting MOGREPS-G forecast file2 ... ',trim(fname) + if (ferror .ge. 1) mogrepsg_struc(n)%fcsttime1 = time1 + + ferror = 0 + order = 2 + call get_mogrepsg_filename(mogrepsg_struc(n)%odir, & + mogrepsg_struc(n)%init_yr, & + mogrepsg_struc(n)%init_mo, & + mogrepsg_struc(n)%init_da, & + mogrepsg_struc(n)%init_hr, & + mogrepsg_struc(n)%fcst_hour, m, fname) + + write(LIS_logunit,*) & + '[INFO] Getting MOGREPS-G forecast file2 ... ', & + trim(fname) call read_mogrepsg(n, m, findex, order, fname, ferror) - if(ferror.ge.1) mogrepsg_struc(n)%fcsttime2=time2 + if (ferror .ge. 1) mogrepsg_struc(n)%fcsttime2 = time2 - !only for T+0 due to mssing LW varaible - mogrepsg_struc(n)%metdata1(4,m,:) = mogrepsg_struc(n)%metdata2(4,m,:) + !only for T+0 due to mssing LW variable + mogrepsg_struc(n)%metdata1(4,m,:) = & + mogrepsg_struc(n)%metdata2(4,m,:) else - ferror=0 - order=2 + ferror = 0 + order = 2 ! met forcings except for pcp - call get_mogrepsg_filename(mogrepsg_struc(n)%odir,mogrepsg_struc(n)%init_yr,& - mogrepsg_struc(n)%init_mo,mogrepsg_struc(n)%init_da,mogrepsg_struc(n)%init_hr,& - mogrepsg_struc(n)%fcst_hour,m,fname) - - write(LIS_logunit,*)'[INFO] Getting MOGREPS-G forecast file2 ... ',trim(fname) + call get_mogrepsg_filename(mogrepsg_struc(n)%odir, & + mogrepsg_struc(n)%init_yr, & + mogrepsg_struc(n)%init_mo, & + mogrepsg_struc(n)%init_da, & + mogrepsg_struc(n)%init_hr, & + mogrepsg_struc(n)%fcst_hour, m, fname) + + write(LIS_logunit,*) & + '[INFO] Getting MOGREPS-G forecast file2 ... ', & + trim(fname) call read_mogrepsg(n, m, findex, order, fname, ferror) - if(ferror.ge.1) mogrepsg_struc(n)%fcsttime2=time2 + if (ferror .ge. 1) mogrepsg_struc(n)%fcsttime2 = time2 !only for T+141 due to mssing LW varaible - if(mogrepsg_struc(n)%fcst_hour == 141) then - mogrepsg_struc(n)%metdata2(4,m,:) = mogrepsg_struc(n)%metdata1(4,m,:) + if (mogrepsg_struc(n)%fcst_hour == 141) then + mogrepsg_struc(n)%metdata2(4,m,:) = & + mogrepsg_struc(n)%metdata1(4,m,:) endif endif ! apply precipitation bias correction (cdf from difference bewteen NAPFA and MOGREPS-G) if (mogrepsg_struc(n)%bc == 1) then - lead_time=floor((float(mogrepsg_struc(n)%fcst_hour))/24)+1 + lead_time=floor((float(mogrepsg_struc(n)%fcst_hour))/24) + 1 if (lead_time > 8) then lead_time = 8 endif - do t=1, LIS_rc%ngrid(n) - if(mogrepsg_struc(n)%metdata2(8,m,t).ne.LIS_rc%udef) then + do t = 1, LIS_rc%ngrid(n) + if (mogrepsg_struc(n)%metdata2(8,m,t) .ne. LIS_rc%udef) then ! only for land pixels if (mogrepsg_struc(n)%bc_param_a(t,lead_time) .ne. LIS_rc%udef) then ! perform centering and scaling - pcp1=mogrepsg_struc(n)%metdata2(8,m,t)-mogrepsg_struc(n)%metdata1(8,m,t) + pcp1= & + mogrepsg_struc(n)%metdata2(8,m,t) - & + mogrepsg_struc(n)%metdata1(8,m,t) if (mogrepsg_struc(n)%bc_std(t,lead_time) .ne. 0) then pcp2=(pcp1-mogrepsg_struc(n)%bc_mean(t,lead_time))/& mogrepsg_struc(n)%bc_std(t,lead_time) @@ -200,27 +222,29 @@ subroutine get_mogrepsg(n, findex) endif ! apply cdf params - pcp2=pcp2*mogrepsg_struc(n)%bc_param_a(t,lead_time)+mogrepsg_struc(n)%bc_param_b(t,lead_time) + pcp2 = pcp2 * & + mogrepsg_struc(n)%bc_param_a(t,lead_time)+mogrepsg_struc(n)%bc_param_b(t,lead_time) ! check for negative precipitation; if the corrected value has negative, keep the original value. - if(pcp2 >= 0) then - mogrepsg_struc(n)%pcp_bc(m,t)=pcp2 + if (pcp2 >= 0) then + mogrepsg_struc(n)%pcp_bc(m,t) = pcp2 else - mogrepsg_struc(n)%pcp_bc(m,t)=pcp1 + mogrepsg_struc(n)%pcp_bc(m,t) = pcp1 endif ! additionally, avoid bias correction for values that are too samll to reduce abnormal noise. if(pcp1 < 0.01) then - mogrepsg_struc(n)%pcp_bc(m,t)=pcp1 + mogrepsg_struc(n)%pcp_bc(m,t) = pcp1 endif else ! for water pixels - mogrepsg_struc(n)%pcp_bc(m,t)=mogrepsg_struc(n)%metdata2(8,m,t)-mogrepsg_struc(n)%metdata1(8,m,t) + mogrepsg_struc(n)%pcp_bc(m,t) = & + mogrepsg_struc(n)%metdata2(8,m,t) - & + mogrepsg_struc(n)%metdata1(8,m,t) endif endif enddo endif - enddo endif - openfile=0 + openfile = 0 end subroutine get_mogrepsg @@ -230,7 +254,8 @@ end subroutine get_mogrepsg ! \label{get_mogrepsg_filename} ! ! !INTERFACE: -subroutine get_mogrepsg_filename(rootdir,yr,mo,da,hr,fc_hr,ens_id,filename) +subroutine get_mogrepsg_filename(rootdir, yr, mo, da, hr, fc_hr, & + ens_id, filename) use LIS_logMod, only: LIS_endrun implicit none @@ -248,12 +273,11 @@ subroutine get_mogrepsg_filename(rootdir,yr,mo,da,hr,fc_hr,ens_id,filename) character(8) :: ftime character(2) :: chr character(3) :: fchr - character(2) :: ens - + character(2) :: ens character(len=36) :: fname write (UNIT=chr, FMT='(i2.2)') hr ! cycle 00/06/12/18 - write (UNIT=fchr, FMT='(i3.3)') fc_hr ! forecast time + write (UNIT=fchr, FMT='(i3.3)') fc_hr ! forecast time write (UNIT=ftime, FMT='(i4, i2.2, i2.2)') yr, mo, da fname = 'prods_op_mogreps-g_' @@ -265,7 +289,7 @@ subroutine get_mogrepsg_filename(rootdir,yr,mo,da,hr,fc_hr,ens_id,filename) else if (ens_id == 1) then write (UNIT=ens, FMT='(i2.2)') ens_id-1 ! start 00 - else + else write (UNIT=ens, FMT='(i2.2)') ens_id+16 ! start 18-34 endif endif diff --git a/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 b/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 index 98dc9d04a..dd27a7bab 100644 --- a/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 +++ b/lis/metforcing/mogreps_g/mogrepsg_forcingMod.F90 @@ -47,14 +47,14 @@ module mogrepsg_forcingMod integer, allocatable :: gindex(:,:) integer :: mi - + integer, allocatable :: n111(:) integer, allocatable :: n121(:) integer, allocatable :: n211(:) integer, allocatable :: n221(:) real, allocatable :: w111(:),w121(:) real, allocatable :: w211(:),w221(:) - + integer, allocatable :: n112(:,:) integer, allocatable :: n122(:,:) integer, allocatable :: n212(:,:) @@ -63,14 +63,14 @@ module mogrepsg_forcingMod real, allocatable :: w212(:,:),w222(:,:) integer, allocatable :: n113(:) - + integer :: findtime1, findtime2 integer :: fcst_hour integer :: init_yr, init_mo, init_da, init_hr - real, allocatable :: metdata1(:,:,:) + real, allocatable :: metdata1(:,:,:) real, allocatable :: metdata2(:,:,:) - - integer :: nmodels + + integer :: nmodels ! only for v-wind due to difference resolution integer :: nrv @@ -78,15 +78,15 @@ module mogrepsg_forcingMod integer, allocatable :: nv121(:) integer, allocatable :: nv211(:) integer, allocatable :: nv221(:) - real, allocatable :: wv111(:),wv121(:) - real, allocatable :: wv211(:),wv221(:) + real, allocatable :: wv111(:), wv121(:) + real, allocatable :: wv211(:), wv221(:) integer, allocatable :: nv112(:,:) integer, allocatable :: nv122(:,:) integer, allocatable :: nv212(:,:) integer, allocatable :: nv222(:,:) - real, allocatable :: wv112(:,:),wv122(:,:) - real, allocatable :: wv212(:,:),wv222(:,:) + real, allocatable :: wv112(:,:), wv122(:,:) + real, allocatable :: wv212(:,:), wv222(:,:) integer, allocatable :: nv113(:) @@ -109,19 +109,19 @@ module mogrepsg_forcingMod ! ! !ROUTINE: init_mogrepsg ! \label{init_mogrepsg} -! +! ! !INTERFACE: subroutine init_mogrepsg(findex) -! !USES: +! !USES: use LIS_coreMod, only : LIS_rc use LIS_timeMgrMod, only : LIS_update_timestep use LIS_logMod, only : LIS_logunit, LIS_endrun implicit none -! !USES: +! !USES: integer, intent(in) :: findex -! -! !DESCRIPTION: +! +! !DESCRIPTION: ! Defines the native resolution of the input forcing for MOGREPS-G ! data. The grid description arrays are based on the decoding ! schemes used by NCEP and followed in the LIS interpolation @@ -139,12 +139,15 @@ subroutine init_mogrepsg(findex) external :: neighbor_interp_input external :: get_cdf_params - write(LIS_logunit,*) "[INFO] Initializing the MOGREPS-G forecast inputs " + write(LIS_logunit,*) & + "[INFO] Initializing the MOGREPS-G forecast inputs " ! Forecast mode -- NOT Available at this time for this forcing reader: if( LIS_rc%forecastMode.eq.1 ) then - write(LIS_logunit,*) '[ERR] Currently the MOGREPS-G forecast forcing reader' - write(LIS_logunit,*) '[ERR] is not set up to run in forecast mode.' + write(LIS_logunit,*) & + '[ERR] Currently the MOGREPS-G forecast forcing reader' + write(LIS_logunit,*) & + '[ERR] is not set up to run in forecast mode.' write(LIS_logunit,*) '[ERR] LIS forecast run-time ending.' call LIS_endrun() endif @@ -164,10 +167,10 @@ subroutine init_mogrepsg(findex) enddo ! 8 - key met field - LIS_rc%met_nf(findex) = 8 + LIS_rc%met_nf(findex) = 8 + + do n = 1, LIS_rc%nnest - do n=1,LIS_rc%nnest - ! Check if starting hour of LIS run matches 00/06/12/18 UTC: if((LIS_rc%shr .ne. 0) .and. (LIS_rc%shr .ne. 6) .and. & (LIS_rc%shr .ne. 12) .and. (LIS_rc%shr .ne. 18)) then @@ -177,10 +180,10 @@ subroutine init_mogrepsg(findex) write(LIS_logunit,*) "[ERR] your lis.config file.." call LIS_endrun() endif - + ! Allocate and initialize MOGREPS-G metforcing data structures: LIS_rc%met_nensem(findex) = mogrepsg_struc(n)%max_ens_members - + allocate(mogrepsg_struc(n)%metdata1(LIS_rc%met_nf(findex),& mogrepsg_struc(n)%max_ens_members,LIS_rc%ngrid(n))) allocate(mogrepsg_struc(n)%metdata2(LIS_rc%met_nf(findex),& @@ -196,7 +199,7 @@ subroutine init_mogrepsg(findex) mogrepsg_struc(n)%metdata1 = 0 mogrepsg_struc(n)%metdata2 = 0 gridDesci = 0 - + gridDesci(n,1) = 0 gridDesci(n,2) = real(mogrepsg_struc(n)%nc) !gnc gridDesci(n,3) = real(mogrepsg_struc(n)%nr) !gnr @@ -352,7 +355,7 @@ subroutine init_mogrepsg(findex) enddo ! precipitation bias correction - do n=1,LIS_rc%nnest + do n = 1, LIS_rc%nnest if (mogrepsg_struc(n)%bc == 1) then allocate(mogrepsg_struc(n)%pcp_bc(mogrepsg_struc(n)%max_ens_members,LIS_rc%ngrid(n))) allocate(mogrepsg_struc(n)%bc_param_a(LIS_rc%ngrid(n),8)) !8: lead time @@ -367,8 +370,9 @@ subroutine init_mogrepsg(findex) mogrepsg_struc(n)%bc_std = 0 ! read cdf parameters - call get_cdf_params(n,mogrepsg_struc(n)%cdf_fname,LIS_rc%mo,& - mogrepsg_struc(n)%bc_param_a, mogrepsg_struc(n)%bc_param_b,& + call get_cdf_params(n,mogrepsg_struc(n)%cdf_fname,LIS_rc%mo, & + mogrepsg_struc(n)%bc_param_a, & + mogrepsg_struc(n)%bc_param_b, & mogrepsg_struc(n)%bc_mean, mogrepsg_struc(n)%bc_std) endif enddo diff --git a/lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 b/lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 index 0ab191a4a..38cd984b4 100644 --- a/lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 +++ b/lis/metforcing/mogreps_g/readcrd_mogrepsg.F90 @@ -16,7 +16,7 @@ ! 26 Jan 2023; Yeosang Yoon, Initial Code ! 01 Jan 2024; Yeosang Yoon; update codes for precpi. bias-correction ! -! !INTERFACE: +! !INTERFACE: subroutine readcrd_mogrepsg() ! !USES: use LIS_logMod @@ -26,55 +26,72 @@ subroutine readcrd_mogrepsg() ! ! !DESCRIPTION: ! -! This routine reads the options specific to MOGREPS-G forecast forcing from -! the LIS configuration file. -! +! This routine reads the options specific to MOGREPS-G forecast forcing from +! the LIS configuration file. +! !EOP implicit none - integer :: n,rc + integer :: n, rc - call ESMF_ConfigFindLabel(LIS_config,"MOGREPS-G forecast forcing directory:",rc=rc) - do n=1,LIS_rc%nnest - call ESMF_ConfigGetAttribute(LIS_config,mogrepsg_struc(n)%odir,rc=rc) - call LIS_verify(rc,'MOGREPS-G forecast forcing directory: not defined') + call ESMF_ConfigFindLabel(LIS_config, & + "MOGREPS-G forecast forcing directory:", rc=rc) + do n = 1, LIS_rc%nnest + call ESMF_ConfigGetAttribute(LIS_config, mogrepsg_struc(n)%odir, & + rc=rc) + call LIS_verify(rc, & + 'MOGREPS-G forecast forcing directory: not defined') enddo - call ESMF_ConfigFindLabel(LIS_config,"MOGREPS-G forecast run mode:",rc=rc) + call ESMF_ConfigFindLabel(LIS_config, "MOGREPS-G forecast run mode:", & + rc=rc) call LIS_verify(rc, 'MOGREPS-G forecast run mode: not defined ') - do n=1,LIS_rc%nnest - call ESMF_ConfigGetAttribute(LIS_config,mogrepsg_struc(n)%runmode,rc=rc) + do n = 1, LIS_rc%nnest + call ESMF_ConfigGetAttribute(LIS_config, & + mogrepsg_struc(n)%runmode, rc=rc) enddo - call ESMF_ConfigFindLabel(LIS_config,"MOGREPS-G forecast number of ensemble members:",rc=rc) - call LIS_verify(rc, 'MOGREPS-G forecast number of ensemble members: not defined') - do n=1,LIS_rc%nnest - call ESMF_ConfigGetAttribute(LIS_config,mogrepsg_struc(n)%max_ens_members,rc=rc) + call ESMF_ConfigFindLabel(LIS_config, & + "MOGREPS-G forecast number of ensemble members:", rc=rc) + call LIS_verify(rc, & + 'MOGREPS-G forecast number of ensemble members: not defined') + do n = 1, LIS_rc%nnest + call ESMF_ConfigGetAttribute(LIS_config, & + mogrepsg_struc(n)%max_ens_members, rc=rc) enddo - call ESMF_ConfigFindLabel(LIS_config,"Apply MOGREPS-G precipitation bias correction:",rc=rc) - call LIS_verify(rc, 'Apply MOGREPS-G precipitation bias correction: not defined') - do n=1,LIS_rc%nnest - call ESMF_ConfigGetAttribute(LIS_config,mogrepsg_struc(n)%bc,rc=rc) + call ESMF_ConfigFindLabel(LIS_config, & + "Apply MOGREPS-G precipitation bias correction:", rc=rc) + call LIS_verify(rc, & + 'Apply MOGREPS-G precipitation bias correction: not defined') + do n = 1, LIS_rc%nnest + call ESMF_ConfigGetAttribute(LIS_config, mogrepsg_struc(n)%bc, rc=rc) enddo - call ESMF_ConfigFindLabel(LIS_config,"MOGREPS-G model CDF file:",rc=rc) + call ESMF_ConfigFindLabel(LIS_config, "MOGREPS-G model CDF file:", rc=rc) call LIS_verify(rc, 'MOGREPS-G model CDF file: not defined') - do n=1,LIS_rc%nnest - call ESMF_ConfigGetAttribute(LIS_config,mogrepsg_struc(n)%cdf_fname,rc=rc) + do n = 1, LIS_rc%nnest + call ESMF_ConfigGetAttribute(LIS_config, & + mogrepsg_struc(n)%cdf_fname, rc=rc) enddo - do n=1,LIS_rc%nnest + do n = 1, LIS_rc%nnest write(LIS_logunit,*) '[INFO] Using MOGREPS-G forecast forcing' - write(LIS_logunit,*) '[INFO] MOGREPS-G forecast forcing directory: ', trim(mogrepsg_struc(n)%odir) - write(LIS_logunit,*) '[INFO] MOGREPS-G forecast run mode: ',mogrepsg_struc(n)%runmode - write(LIS_logunit,*) '[INFO] MOGREPS-G forecast number of ensemble members:',& + write(LIS_logunit,*) & + '[INFO] MOGREPS-G forecast forcing directory: ', & + trim(mogrepsg_struc(n)%odir) + write(LIS_logunit,*) '[INFO] MOGREPS-G forecast run mode: ', & + mogrepsg_struc(n)%runmode + write(LIS_logunit,*) & + '[INFO] MOGREPS-G forecast number of ensemble members:', & mogrepsg_struc(n)%max_ens_members - write(LIS_logunit,*) '[INFO] Using MOGREPS-G precipitation bias correction:',& + write(LIS_logunit,*) & + '[INFO] Using MOGREPS-G precipitation bias correction:',& mogrepsg_struc(n)%bc if (mogrepsg_struc(n)%bc == 1) then - write(LIS_logunit,*) '[INFO] MOGREPS-G model CDF file: ', trim(mogrepsg_struc(n)%cdf_fname) + write(LIS_logunit,*) '[INFO] MOGREPS-G model CDF file: ', & + trim(mogrepsg_struc(n)%cdf_fname) endif enddo end subroutine readcrd_mogrepsg diff --git a/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 b/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 index ea6537c25..c647d1c1a 100644 --- a/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 +++ b/lis/metforcing/mogreps_g/timeinterp_mogrepsg.F90 @@ -59,150 +59,172 @@ subroutine timeinterp_mogrepsg(n,findex) real :: wt1, wt2, swt1, swt2 real :: gmt1, gmt2 integer :: t,index1 - integer :: bdoy,byr,bmo,bda,bhr,bmn - real*8 :: btime,newtime1,newtime2 - real :: tempgmt1,tempgmt2,tempbts - integer :: tempbdoy,tempbyr,tempbmo,tempbda,tempbhr,tempbmn,tempbss + integer :: bdoy, byr, bmo, bda, bhr, bmn + real*8 :: btime, newtime1, newtime2 + real :: tempgmt1, tempgmt2, tempbts + integer :: tempbdoy, tempbyr, tempbmo, tempbda, tempbhr, tempbmn, tempbss integer :: status - type(ESMF_Field) :: tmpField,q2Field,uField,vField,swdField,lwdField - type(ESMF_Field) :: psurfField,pcpField - real,pointer :: tmp(:),q2(:),uwind(:),vwind(:) - real,pointer :: swd(:),lwd(:),psurf(:),pcp(:) + type(ESMF_Field) :: tmpField, q2Field, uField, vField, swdField, & + lwdField + type(ESMF_Field) :: psurfField, pcpField + real, pointer :: tmp(:), q2(:), uwind(:), vwind(:) + real, pointer :: swd(:), lwd(:), psurf(:), pcp(:) integer :: mfactor, m, k, tid external :: zterp ! ________________________________________ btime=mogrepsg_struc(n)%fcsttime1 - call LIS_time2date(btime,bdoy,gmt1,byr,bmo,bda,bhr,bmn) - - tempbdoy=bdoy - tempgmt1=gmt1 - tempbyr=byr - tempbmo=bmo - tempbda=bda - tempbhr=bhr - if (tempbhr.eq.24) tempbhr=0 - tempbmn=bmn - tempbss=0 - tempbts=0 - call LIS_tick(newtime1,tempbdoy,tempgmt1,& - tempbyr,tempbmo,tempbda,tempbhr,tempbmn, & - tempbss,tempbts) - - btime=mogrepsg_struc(n)%fcsttime2 - call LIS_time2date(btime,bdoy,gmt2,byr,bmo,bda,bhr,bmn) - - tempbdoy=bdoy - tempgmt2=gmt2 - tempbyr=byr - tempbmo=bmo - tempbda=bda - tempbhr=bhr - if (tempbhr.eq.24) tempbhr=0 - tempbmn=bmn - tempbss=0 - tempbts=0 - call LIS_tick(newtime2,tempbdoy,tempgmt2,& - tempbyr,tempbmo,tempbda,tempbhr,tempbmn,& - tempbss,tempbts) + call LIS_time2date(btime, bdoy, gmt1, byr, bmo, bda, bhr, bmn) + + tempbdoy = bdoy + tempgmt1 = gmt1 + tempbyr = byr + tempbmo = bmo + tempbda = bda + tempbhr = bhr + if (tempbhr.eq.24) tempbhr = 0 + tempbmn = bmn + tempbss = 0 + tempbts = 0 + call LIS_tick(newtime1, tempbdoy, tempgmt1, & + tempbyr, tempbmo, tempbda, tempbhr, tempbmn, & + tempbss, tempbts) + + btime = mogrepsg_struc(n)%fcsttime2 + call LIS_time2date(btime, bdoy, gmt2, byr, bmo, bda, bhr, bmn) + + tempbdoy = bdoy + tempgmt2 = gmt2 + tempbyr = byr + tempbmo = bmo + tempbda = bda + tempbhr = bhr + if (tempbhr.eq.24) tempbhr = 0 + tempbmn = bmn + tempbss = 0 + tempbts = 0 + call LIS_tick(newtime2, tempbdoy, tempgmt2,& + tempbyr, tempbmo, tempbda, tempbhr, tempbmn,& + tempbss, tempbts) !Interpolate Data in Time - wt1=real((mogrepsg_struc(n)%fcsttime2-LIS_rc%time)/ & + wt1 =real((mogrepsg_struc(n)%fcsttime2-LIS_rc%time)/ & (mogrepsg_struc(n)%fcsttime2-mogrepsg_struc(n)%fcsttime1)) - wt2=1.0-wt1 - swt1=real((newtime2-LIS_rc%time)/(newtime2-newtime1)) - swt2=1.0-swt1 + wt2 = 1.0 - wt1 + swt1 = real((newtime2-LIS_rc%time)/(newtime2-newtime1)) + swt2 = 1.0 - swt1 - call ESMF_StateGet(LIS_FORC_Base_State(n,findex),LIS_FORC_Tair%varname(1),tmpField,& + call ESMF_StateGet(LIS_FORC_Base_State(n,findex), & + LIS_FORC_Tair%varname(1), tmpField,& rc=status) - call LIS_verify(status, 'Error: Enable Tair in the forcing variables list') + call LIS_verify(status, & + 'Error: Enable Tair in the forcing variables list') - call ESMF_StateGet(LIS_FORC_Base_State(n,findex),LIS_FORC_Qair%varname(1),q2Field,& + call ESMF_StateGet(LIS_FORC_Base_State(n,findex), & + LIS_FORC_Qair%varname(1), q2Field, & rc=status) - call LIS_verify(status, 'Error: Enable Qair in the forcing variables list') + call LIS_verify(status, & + 'Error: Enable Qair in the forcing variables list') - call ESMF_StateGet(LIS_FORC_Base_State(n,findex),LIS_FORC_SWdown%varname(1),swdField,& + call ESMF_StateGet(LIS_FORC_Base_State(n,findex), & + LIS_FORC_SWdown%varname(1), swdField, & rc=status) - call LIS_verify(status, 'Error: Enable SWdown in the forcing variables list') + call LIS_verify(status, & + 'Error: Enable SWdown in the forcing variables list') - call ESMF_StateGet(LIS_FORC_Base_State(n,findex),LIS_FORC_LWdown%varname(1),lwdField,& + call ESMF_StateGet(LIS_FORC_Base_State(n,findex), & + LIS_FORC_LWdown%varname(1), lwdField, & rc=status) - call LIS_verify(status, 'Error: Enable LWdown in the forcing variables list') + call LIS_verify(status, & + 'Error: Enable LWdown in the forcing variables list') - call ESMF_StateGet(LIS_FORC_Base_State(n,findex),LIS_FORC_Wind_E%varname(1),uField,& + call ESMF_StateGet(LIS_FORC_Base_State(n,findex), & + LIS_FORC_Wind_E%varname(1), uField, & rc=status) - call LIS_verify(status, 'Error: Enable Wind_E in the forcing variables list') + call LIS_verify(status, & + 'Error: Enable Wind_E in the forcing variables list') - call ESMF_StateGet(LIS_FORC_Base_State(n,findex),LIS_FORC_Wind_N%varname(1),vField,& + call ESMF_StateGet(LIS_FORC_Base_State(n,findex), & + LIS_FORC_Wind_N%varname(1), vField, & rc=status) - call LIS_verify(status, 'Error: Enable Wind_N in the forcing variables list') + call LIS_verify(status, & + 'Error: Enable Wind_N in the forcing variables list') - call ESMF_StateGet(LIS_FORC_Base_State(n,findex),LIS_FORC_Psurf%varname(1),psurfField,& + call ESMF_StateGet(LIS_FORC_Base_State(n,findex), & + LIS_FORC_Psurf%varname(1), psurfField,& rc=status) - call LIS_verify(status, 'Error: Enable Psurf in the forcing variables list') + call LIS_verify(status, & + 'Error: Enable Psurf in the forcing variables list') - call ESMF_StateGet(LIS_FORC_Base_State(n,findex),LIS_FORC_Rainf%varname(1),pcpField,& + call ESMF_StateGet(LIS_FORC_Base_State(n,findex), & + LIS_FORC_Rainf%varname(1), pcpField, & rc=status) - call LIS_verify(status, 'Error: Enable Rainf in the forcing variables list') + call LIS_verify(status, & + 'Error: Enable Rainf in the forcing variables list') - - call ESMF_FieldGet(tmpField,localDE=0,farrayPtr=tmp,rc=status) + call ESMF_FieldGet(tmpField, localDE=0, farrayPtr=tmp, rc=status) call LIS_verify(status) - call ESMF_FieldGet(q2Field,localDE=0,farrayPtr=q2,rc=status) + call ESMF_FieldGet(q2Field, localDE=0, farrayPtr=q2, rc=status) call LIS_verify(status) - call ESMF_FieldGet(swdField,localDE=0,farrayPtr=swd,rc=status) + call ESMF_FieldGet(swdField, localDE=0, farrayPtr=swd, rc=status) call LIS_verify(status) - call ESMF_FieldGet(lwdField,localDE=0,farrayPtr=lwd,rc=status) + call ESMF_FieldGet(lwdField, localDE=0, farrayPtr=lwd, rc=status) call LIS_verify(status) - call ESMF_FieldGet(uField,localDE=0,farrayPtr=uwind,rc=status) + call ESMF_FieldGet(uField, localDE=0, farrayPtr=uwind, rc=status) call LIS_verify(status) - call ESMF_FieldGet(vField,localDE=0,farrayPtr=vwind,rc=status) + call ESMF_FieldGet(vField, localDE=0, farrayPtr=vwind, rc=status) call LIS_verify(status) - call ESMF_FieldGet(psurfField,localDE=0,farrayPtr=psurf,rc=status) + call ESMF_FieldGet(psurfField, localDE=0, farrayPtr=psurf, rc=status) call LIS_verify(status) - call ESMF_FieldGet(pcpField,localDE=0,farrayPtr=pcp,rc=status) + call ESMF_FieldGet(pcpField, localDE=0, farrayPtr=pcp, rc=status) call LIS_verify(status) ! Metforcing ensemble member count factor - mfactor = LIS_rc%nensem(n)/mogrepsg_struc(n)%max_ens_members + mfactor = LIS_rc%nensem(n) / mogrepsg_struc(n)%max_ens_members ! Downward shortwave radiation (average): - do t=1,LIS_rc%ntiles(n)/LIS_rc%nensem(n) - do m=1,mogrepsg_struc(n)%max_ens_members - do k=1,mfactor - tid = (t-1)*LIS_rc%nensem(n)+(m-1)*mfactor+k + do t = 1, LIS_rc%ntiles(n) / LIS_rc%nensem(n) + do m = 1, mogrepsg_struc(n)%max_ens_members + do k = 1, mfactor + tid = (t - 1) * LIS_rc%nensem(n)+(m-1)*mfactor + k index1 = LIS_domain(n)%tile(tid)%index - zdoy=LIS_rc%doy + zdoy = LIS_rc%doy ! Compute and apply zenith angle weights - call zterp(1,LIS_domain(n)%grid(index1)%lat,& - LIS_domain(n)%grid(index1)%lon,& - gmt1,gmt2,LIS_rc%gmt,zdoy,zw1,zw2,czb,cze,czm,LIS_rc) - - if(mogrepsg_struc(n)%metdata1(3,m,index1).ne.LIS_rc%udef.and.& - mogrepsg_struc(n)%metdata2(3,m,index1).ne.LIS_rc%udef) then - swd(tid) = mogrepsg_struc(n)%metdata1(3,m,index1)*zw1+& - mogrepsg_struc(n)%metdata2(3,m,index1)*zw2 + call zterp(1, LIS_domain(n)%grid(index1)%lat, & + LIS_domain(n)%grid(index1)%lon, & + gmt1, gmt2, LIS_rc%gmt, zdoy, zw1, zw2, czb, cze, czm, & + LIS_rc) + + if (mogrepsg_struc(n)%metdata1(3,m,index1) .ne. LIS_rc%udef & + .and. & + mogrepsg_struc(n)%metdata2(3,m,index1).ne. LIS_rc%udef) & + then + swd(tid) = mogrepsg_struc(n)%metdata1(3,m,index1) * zw1 + & + mogrepsg_struc(n)%metdata2(3,m,index1) * zw2 !swd(tid) = zw1 * mogrepsg_struc(n)%metdata2(3,m,index1) ! In cases of small cos(zenith) angles, use linear weighting to avoid overly large weights - if((swd(tid).gt.mogrepsg_struc(n)%metdata1(3,m,index1).and. & - swd(tid).gt.mogrepsg_struc(n)%metdata2(3,m,index1)).and. & - (czb.lt.0.1.or.cze.lt.0.1))then + if ((swd(tid) .gt. mogrepsg_struc(n)%metdata1(3,m,index1) & + .and. & + swd(tid) .gt. mogrepsg_struc(n)%metdata2(3,m,index1)) & + .and. & + (czb .lt. 0.1 .or. cze .lt. 0.1)) then swd(tid) = mogrepsg_struc(n)%metdata1(3,m,index1)*swt1+ & mogrepsg_struc(n)%metdata2(3,m,index1)*swt2 endif if (swd(t).gt.LIS_CONST_SOLAR) then - write(unit=LIS_logunit,fmt=*)'[WARN] sw radiation too high!!' + write(unit=LIS_logunit,fmt=*) & + '[WARN] sw radiation too high!!' write(unit=LIS_logunit,fmt=*)'[WARN] it is',swd(t) write(unit=LIS_logunit,fmt=*)'[WARN] mogrepsgdata1=',& mogrepsg_struc(n)%metdata1(3,m,index1) @@ -210,22 +232,24 @@ subroutine timeinterp_mogrepsg(n,findex) mogrepsg_struc(n)%metdata2(3,m,index1) write(unit=LIS_logunit,fmt=*)'[WARN] zw1=',zw1,'zw2=',zw2 swd(t) = LIS_CONST_SOLAR - write(unit=LIS_logunit,fmt=*)'[WARN] forcing set to ',swd(t) + write(unit=LIS_logunit,fmt=*) & + '[WARN] forcing set to ',swd(t) endif endif - if ((swd(t).ne.LIS_rc%udef).and.(swd(t).lt.0)) then - if (swd(t).gt.-0.00001) then + if ((swd(t) .ne. LIS_rc%udef) .and. (swd(t) .lt. 0)) then + if (swd(t) .gt. -0.00001) then swd(t) = 0.0 else - write(LIS_logunit,*) '[ERR] timeinterp_mogrepsg -- Stopping because ', & + write(LIS_logunit,*) & + '[ERR] timeinterp_mogrepsg -- Stopping because ', & 'forcing not udef but lt 0,' write(LIS_logunit,*)'[ERR] timeinterp_mogrepsg -- ', & - t,swd(t),mogrepsg_struc(n)%metdata2(3,m,index1), & - ' (',LIS_localPet,')' + t,swd(t),mogrepsg_struc(n)%metdata2(3,m,index1), & + ' (',LIS_localPet,')' call LIS_endrun endif - endif + endif enddo enddo enddo @@ -234,31 +258,35 @@ subroutine timeinterp_mogrepsg(n,findex) ! precip variable Block Interpolation !----------------------------------------------------------------------- ! Total precipitation field (accumulated): - do t=1,LIS_rc%ntiles(n)/LIS_rc%nensem(n) - do m=1,mogrepsg_struc(n)%max_ens_members - do k=1,mfactor - tid = (t-1)*LIS_rc%nensem(n)+(m-1)*mfactor+k + do t = 1, LIS_rc%ntiles(n) / LIS_rc%nensem(n) + do m = 1, mogrepsg_struc(n)%max_ens_members + do k = 1, mfactor + tid = (t - 1) * LIS_rc%nensem(n) + (m - 1) * mfactor + k index1 = LIS_domain(n)%tile(tid)%index ! apply precipitation bias correction if (mogrepsg_struc(n)%bc == 1) then !1 - use; or 0 - if(mogrepsg_struc(n)%pcp_bc(m,index1).ne.LIS_rc%udef) then + if (mogrepsg_struc(n)%pcp_bc(m,index1) .ne. & + LIS_rc%udef) then ! account for the accum fields - pcp(tid)=mogrepsg_struc(n)%pcp_bc(m,index1)/real(3600*3) - if(pcp(tid).lt.0) then + pcp(tid) = mogrepsg_struc(n)%pcp_bc(m,index1) / & + real(3600*3) + if (pcp(tid) .lt. 0) then pcp(tid) = 0.0 endif endif else !don't apply bias correction - if(mogrepsg_struc(n)%metdata2(8,m,index1).ne.LIS_rc%udef) then + if (mogrepsg_struc(n)%metdata2(8,m,index1) .ne. & + LIS_rc%udef) then ! account for the accum fields - pcp(tid)=(mogrepsg_struc(n)%metdata2(8,m,index1)-mogrepsg_struc(n)%metdata1(8,m,index1))/real(3600*3) - if(pcp(tid).lt.0) then + pcp(tid) = (mogrepsg_struc(n)%metdata2(8,m,index1) - & + mogrepsg_struc(n)%metdata1(8,m,index1)) / & + real(3600*3) + if (pcp(tid) .lt. 0) then pcp(tid) = 0.0 endif endif endif - enddo enddo enddo @@ -266,47 +294,59 @@ subroutine timeinterp_mogrepsg(n,findex) !----------------------------------------------------------------------- ! Linearly interpolate everything else !----------------------------------------------------------------------- - do t=1,LIS_rc%ntiles(n)/LIS_rc%nensem(n) - do m=1,mogrepsg_struc(n)%max_ens_members - do k=1,mfactor - tid = (t-1)*LIS_rc%nensem(n)+(m-1)*mfactor+k + do t = 1, LIS_rc%ntiles(n) / LIS_rc%nensem(n) + do m = 1, mogrepsg_struc(n)%max_ens_members + do k = 1, mfactor + tid = (t - 1)*LIS_rc%nensem(n) + (m - 1) * mfactor + k index1 = LIS_domain(n)%tile(tid)%index - + ! 2-meter air temp - if((mogrepsg_struc(n)%metdata1(1,m,index1).ne.LIS_rc%udef).and.& - (mogrepsg_struc(n)%metdata2(1,m,index1).ne.LIS_rc%udef)) then - tmp(tid) = mogrepsg_struc(n)%metdata1(1,m,index1)*wt1 + & - mogrepsg_struc(n)%metdata2(1,m,index1)*wt2 + if ((mogrepsg_struc(n)%metdata1(1,m,index1) .ne. LIS_rc%udef) & + .and. & + (mogrepsg_struc(n)%metdata2(1,m,index1) .ne. & + LIS_rc%udef)) then + tmp(tid) = mogrepsg_struc(n)%metdata1(1,m,index1) * wt1 + & + mogrepsg_struc(n)%metdata2(1,m,index1) * wt2 endif ! Specific humidity - if((mogrepsg_struc(n)%metdata1(2,m,index1).ne.LIS_rc%udef).and.& - (mogrepsg_struc(n)%metdata2(2,m,index1).ne.LIS_rc%udef)) then - q2(tid) = mogrepsg_struc(n)%metdata1(2,m,index1)*wt1 + & - mogrepsg_struc(n)%metdata2(2,m,index1)*wt2 + if ((mogrepsg_struc(n)%metdata1(2,m,index1) .ne. LIS_rc%udef) & + .and. & + (mogrepsg_struc(n)%metdata2(2,m,index1) .ne. & + LIS_rc%udef)) then + q2(tid) = mogrepsg_struc(n)%metdata1(2,m,index1) * wt1 + & + mogrepsg_struc(n)%metdata2(2,m,index1) * wt2 endif ! Downward longwave field - if((mogrepsg_struc(n)%metdata1(4,m,index1).ne.LIS_rc%udef).and.& - (mogrepsg_struc(n)%metdata2(4,m,index1).ne.LIS_rc%udef)) then - lwd(tid) = mogrepsg_struc(n)%metdata1(4,m,index1)*wt1 + & - mogrepsg_struc(n)%metdata2(4,m,index1)*wt2 + if ((mogrepsg_struc(n)%metdata1(4,m,index1) .ne. & + LIS_rc%udef) .and. & + (mogrepsg_struc(n)%metdata2(4,m,index1) .ne. & + LIS_rc%udef)) then + lwd(tid) = mogrepsg_struc(n)%metdata1(4,m,index1) * wt1 + & + mogrepsg_struc(n)%metdata2(4,m,index1) * wt2 endif ! U-wind component - if((mogrepsg_struc(n)%metdata1(5,m,index1).ne.LIS_rc%udef).and.& - (mogrepsg_struc(n)%metdata2(5,m,index1).ne.LIS_rc%udef)) then - uwind(tid) = mogrepsg_struc(n)%metdata1(5,m,index1)*wt1+& - mogrepsg_struc(n)%metdata2(5,m,index1)*wt2 + if ((mogrepsg_struc(n)%metdata1(5,m,index1) .ne. LIS_rc%udef) & + .and. & + (mogrepsg_struc(n)%metdata2(5,m,index1) .ne. & + LIS_rc%udef)) then + uwind(tid) = mogrepsg_struc(n)%metdata1(5,m,index1) * wt1 & + + mogrepsg_struc(n)%metdata2(5,m,index1) * wt2 endif ! V-wind component - if((mogrepsg_struc(n)%metdata1(6,m,index1).ne.LIS_rc%udef).and.& - (mogrepsg_struc(n)%metdata2(6,m,index1).ne.LIS_rc%udef)) then - vwind(tid) = mogrepsg_struc(n)%metdata1(6,m,index1)*wt1 + & - mogrepsg_struc(n)%metdata2(6,m,index1)*wt2 + if ((mogrepsg_struc(n)%metdata1(6,m,index1) .ne. LIS_rc%udef) & + .and. & + (mogrepsg_struc(n)%metdata2(6,m,index1) .ne. & + LIS_rc%udef)) then + vwind(tid) = mogrepsg_struc(n)%metdata1(6,m,index1) * wt1 & + + mogrepsg_struc(n)%metdata2(6,m,index1) * wt2 endif ! Surface pressure field - if((mogrepsg_struc(n)%metdata1(7,m,index1).ne.LIS_rc%udef).and.& - (mogrepsg_struc(n)%metdata2(7,m,index1).ne.LIS_rc%udef)) then - psurf(tid) = mogrepsg_struc(n)%metdata1(7,m,index1)*wt1 + & - mogrepsg_struc(n)%metdata2(7,m,index1)*wt2 + if ((mogrepsg_struc(n)%metdata1(7,m,index1) .ne. LIS_rc%udef) & + .and. & + (mogrepsg_struc(n)%metdata2(7,m,index1) .ne. & + LIS_rc%udef)) then + psurf(tid) = mogrepsg_struc(n)%metdata1(7,m,index1) * wt1 & + + mogrepsg_struc(n)%metdata2(7,m,index1) * wt2 endif enddo enddo